<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

  
  <title>Java 基础G | Threadv</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848">
<meta name="keywords" content="java">
<meta property="og:type" content="article">
<meta property="og:title" content="Java 基础G">
<meta property="og:url" content="http://yoursite.com/2019/04/06/GItChat_java/index.html">
<meta property="og:site_name" content="Threadv">
<meta property="og:description" content="12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210">
<meta property="og:updated_time" content="2020-03-29T11:01:38.358Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Java 基础G">
<meta name="twitter:description" content="12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210">
  
    <link rel="alternate" href="/atom.xml" title="Threadv" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png">
  
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link rel="stylesheet" href="/css/style.css">
</head>

<body>
  <div id="container">
    <div id="wrap">
      <header id="header">
  <div id="banner"></div>
  <div id="header-outer" class="outer">
    <div id="header-title" class="inner">
      <h1 id="logo-wrap">
        <a href="/" id="logo">Threadv</a>
      </h1>
      
    </div>
    <div id="header-inner" class="inner">
      <nav id="main-nav">
        <a id="main-nav-toggle" class="nav-icon"></a>
        
          <a class="main-nav-link" href="/">Home</a>
        
          <a class="main-nav-link" href="/archives">Archives</a>
        
      </nav>
      <nav id="sub-nav">
        
          <a id="nav-rss-link" class="nav-icon" href="/atom.xml" title="RSS Feed"></a>
        
        <a id="nav-search-btn" class="nav-icon" title="Search"></a>
      </nav>
      <div id="search-form-wrap">
        <form action="//google.com/search" method="get" accept-charset="UTF-8" class="search-form"><input type="search" name="q" class="search-form-input" placeholder="Search"><button type="submit" class="search-form-submit">&#xF002;</button><input type="hidden" name="sitesearch" value="http://yoursite.com"></form>
      </div>
    </div>
  </div>
</header>
      <div class="outer">
        <section id="main"><article id="post-GItChat_java" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-meta">
    <a href="/2019/04/06/GItChat_java/" class="article-date">
  <time datetime="2019-04-06T03:53:43.000Z" itemprop="datePublished">2019-04-06</time>
</a>
    
  </div>
  <div class="article-inner">
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      Java 基础G
    </h1>
  

      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
        <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br><span class="line">574</span><br><span class="line">575</span><br><span class="line">576</span><br><span class="line">577</span><br><span class="line">578</span><br><span class="line">579</span><br><span class="line">580</span><br><span class="line">581</span><br><span class="line">582</span><br><span class="line">583</span><br><span class="line">584</span><br><span class="line">585</span><br><span class="line">586</span><br><span class="line">587</span><br><span class="line">588</span><br><span class="line">589</span><br><span class="line">590</span><br><span class="line">591</span><br><span class="line">592</span><br><span class="line">593</span><br><span class="line">594</span><br><span class="line">595</span><br><span class="line">596</span><br><span class="line">597</span><br><span class="line">598</span><br><span class="line">599</span><br><span class="line">600</span><br><span class="line">601</span><br><span class="line">602</span><br><span class="line">603</span><br><span class="line">604</span><br><span class="line">605</span><br><span class="line">606</span><br><span class="line">607</span><br><span class="line">608</span><br><span class="line">609</span><br><span class="line">610</span><br><span class="line">611</span><br><span class="line">612</span><br><span class="line">613</span><br><span class="line">614</span><br><span class="line">615</span><br><span class="line">616</span><br><span class="line">617</span><br><span class="line">618</span><br><span class="line">619</span><br><span class="line">620</span><br><span class="line">621</span><br><span class="line">622</span><br><span class="line">623</span><br><span class="line">624</span><br><span class="line">625</span><br><span class="line">626</span><br><span class="line">627</span><br><span class="line">628</span><br><span class="line">629</span><br><span class="line">630</span><br><span class="line">631</span><br><span class="line">632</span><br><span class="line">633</span><br><span class="line">634</span><br><span class="line">635</span><br><span class="line">636</span><br><span class="line">637</span><br><span class="line">638</span><br><span class="line">639</span><br><span class="line">640</span><br><span class="line">641</span><br><span class="line">642</span><br><span class="line">643</span><br><span class="line">644</span><br><span class="line">645</span><br><span class="line">646</span><br><span class="line">647</span><br><span class="line">648</span><br><span class="line">649</span><br><span class="line">650</span><br><span class="line">651</span><br><span class="line">652</span><br><span class="line">653</span><br><span class="line">654</span><br><span class="line">655</span><br><span class="line">656</span><br><span class="line">657</span><br><span class="line">658</span><br><span class="line">659</span><br><span class="line">660</span><br><span class="line">661</span><br><span class="line">662</span><br><span class="line">663</span><br><span class="line">664</span><br><span class="line">665</span><br><span class="line">666</span><br><span class="line">667</span><br><span class="line">668</span><br><span class="line">669</span><br><span class="line">670</span><br><span class="line">671</span><br><span class="line">672</span><br><span class="line">673</span><br><span class="line">674</span><br><span class="line">675</span><br><span class="line">676</span><br><span class="line">677</span><br><span class="line">678</span><br><span class="line">679</span><br><span class="line">680</span><br><span class="line">681</span><br><span class="line">682</span><br><span class="line">683</span><br><span class="line">684</span><br><span class="line">685</span><br><span class="line">686</span><br><span class="line">687</span><br><span class="line">688</span><br><span class="line">689</span><br><span class="line">690</span><br><span class="line">691</span><br><span class="line">692</span><br><span class="line">693</span><br><span class="line">694</span><br><span class="line">695</span><br><span class="line">696</span><br><span class="line">697</span><br><span class="line">698</span><br><span class="line">699</span><br><span class="line">700</span><br><span class="line">701</span><br><span class="line">702</span><br><span class="line">703</span><br><span class="line">704</span><br><span class="line">705</span><br><span class="line">706</span><br><span class="line">707</span><br><span class="line">708</span><br><span class="line">709</span><br><span class="line">710</span><br><span class="line">711</span><br><span class="line">712</span><br><span class="line">713</span><br><span class="line">714</span><br><span class="line">715</span><br><span class="line">716</span><br><span class="line">717</span><br><span class="line">718</span><br><span class="line">719</span><br><span class="line">720</span><br><span class="line">721</span><br><span class="line">722</span><br><span class="line">723</span><br><span class="line">724</span><br><span class="line">725</span><br><span class="line">726</span><br><span class="line">727</span><br><span class="line">728</span><br><span class="line">729</span><br><span class="line">730</span><br><span class="line">731</span><br><span class="line">732</span><br><span class="line">733</span><br><span class="line">734</span><br><span class="line">735</span><br><span class="line">736</span><br><span class="line">737</span><br><span class="line">738</span><br><span class="line">739</span><br><span class="line">740</span><br><span class="line">741</span><br><span class="line">742</span><br><span class="line">743</span><br><span class="line">744</span><br><span class="line">745</span><br><span class="line">746</span><br><span class="line">747</span><br><span class="line">748</span><br><span class="line">749</span><br><span class="line">750</span><br><span class="line">751</span><br><span class="line">752</span><br><span class="line">753</span><br><span class="line">754</span><br><span class="line">755</span><br><span class="line">756</span><br><span class="line">757</span><br><span class="line">758</span><br><span class="line">759</span><br><span class="line">760</span><br><span class="line">761</span><br><span class="line">762</span><br><span class="line">763</span><br><span class="line">764</span><br><span class="line">765</span><br><span class="line">766</span><br><span class="line">767</span><br><span class="line">768</span><br><span class="line">769</span><br><span class="line">770</span><br><span class="line">771</span><br><span class="line">772</span><br><span class="line">773</span><br><span class="line">774</span><br><span class="line">775</span><br><span class="line">776</span><br><span class="line">777</span><br><span class="line">778</span><br><span class="line">779</span><br><span class="line">780</span><br><span class="line">781</span><br><span class="line">782</span><br><span class="line">783</span><br><span class="line">784</span><br><span class="line">785</span><br><span class="line">786</span><br><span class="line">787</span><br><span class="line">788</span><br><span class="line">789</span><br><span class="line">790</span><br><span class="line">791</span><br><span class="line">792</span><br><span class="line">793</span><br><span class="line">794</span><br><span class="line">795</span><br><span class="line">796</span><br><span class="line">797</span><br><span class="line">798</span><br><span class="line">799</span><br><span class="line">800</span><br><span class="line">801</span><br><span class="line">802</span><br><span class="line">803</span><br><span class="line">804</span><br><span class="line">805</span><br><span class="line">806</span><br><span class="line">807</span><br><span class="line">808</span><br><span class="line">809</span><br><span class="line">810</span><br><span class="line">811</span><br><span class="line">812</span><br><span class="line">813</span><br><span class="line">814</span><br><span class="line">815</span><br><span class="line">816</span><br><span class="line">817</span><br><span class="line">818</span><br><span class="line">819</span><br><span class="line">820</span><br><span class="line">821</span><br><span class="line">822</span><br><span class="line">823</span><br><span class="line">824</span><br><span class="line">825</span><br><span class="line">826</span><br><span class="line">827</span><br><span class="line">828</span><br><span class="line">829</span><br><span class="line">830</span><br><span class="line">831</span><br><span class="line">832</span><br><span class="line">833</span><br><span class="line">834</span><br><span class="line">835</span><br><span class="line">836</span><br><span class="line">837</span><br><span class="line">838</span><br><span class="line">839</span><br><span class="line">840</span><br><span class="line">841</span><br><span class="line">842</span><br><span class="line">843</span><br><span class="line">844</span><br><span class="line">845</span><br><span class="line">846</span><br><span class="line">847</span><br><span class="line">848</span><br><span class="line">849</span><br><span class="line">850</span><br><span class="line">851</span><br><span class="line">852</span><br><span class="line">853</span><br><span class="line">854</span><br><span class="line">855</span><br><span class="line">856</span><br><span class="line">857</span><br><span class="line">858</span><br><span class="line">859</span><br><span class="line">860</span><br><span class="line">861</span><br><span class="line">862</span><br><span class="line">863</span><br><span class="line">864</span><br><span class="line">865</span><br><span class="line">866</span><br><span class="line">867</span><br><span class="line">868</span><br><span class="line">869</span><br><span class="line">870</span><br><span class="line">871</span><br><span class="line">872</span><br><span class="line">873</span><br><span class="line">874</span><br><span class="line">875</span><br><span class="line">876</span><br><span class="line">877</span><br><span class="line">878</span><br><span class="line">879</span><br><span class="line">880</span><br><span class="line">881</span><br><span class="line">882</span><br><span class="line">883</span><br><span class="line">884</span><br><span class="line">885</span><br><span class="line">886</span><br><span class="line">887</span><br><span class="line">888</span><br><span class="line">889</span><br><span class="line">890</span><br><span class="line">891</span><br><span class="line">892</span><br><span class="line">893</span><br><span class="line">894</span><br><span class="line">895</span><br><span class="line">896</span><br><span class="line">897</span><br><span class="line">898</span><br><span class="line">899</span><br><span class="line">900</span><br><span class="line">901</span><br><span class="line">902</span><br><span class="line">903</span><br><span class="line">904</span><br><span class="line">905</span><br><span class="line">906</span><br><span class="line">907</span><br><span class="line">908</span><br><span class="line">909</span><br><span class="line">910</span><br><span class="line">911</span><br><span class="line">912</span><br><span class="line">913</span><br><span class="line">914</span><br><span class="line">915</span><br><span class="line">916</span><br><span class="line">917</span><br><span class="line">918</span><br><span class="line">919</span><br><span class="line">920</span><br><span class="line">921</span><br><span class="line">922</span><br><span class="line">923</span><br><span class="line">924</span><br><span class="line">925</span><br><span class="line">926</span><br><span class="line">927</span><br><span class="line">928</span><br><span class="line">929</span><br><span class="line">930</span><br><span class="line">931</span><br><span class="line">932</span><br><span class="line">933</span><br><span class="line">934</span><br><span class="line">935</span><br><span class="line">936</span><br><span class="line">937</span><br><span class="line">938</span><br><span class="line">939</span><br><span class="line">940</span><br><span class="line">941</span><br><span class="line">942</span><br><span class="line">943</span><br><span class="line">944</span><br><span class="line">945</span><br><span class="line">946</span><br><span class="line">947</span><br><span class="line">948</span><br><span class="line">949</span><br><span class="line">950</span><br><span class="line">951</span><br><span class="line">952</span><br><span class="line">953</span><br><span class="line">954</span><br><span class="line">955</span><br><span class="line">956</span><br><span class="line">957</span><br><span class="line">958</span><br><span class="line">959</span><br><span class="line">960</span><br><span class="line">961</span><br><span class="line">962</span><br><span class="line">963</span><br><span class="line">964</span><br><span class="line">965</span><br><span class="line">966</span><br><span class="line">967</span><br><span class="line">968</span><br><span class="line">969</span><br><span class="line">970</span><br><span class="line">971</span><br><span class="line">972</span><br><span class="line">973</span><br><span class="line">974</span><br><span class="line">975</span><br><span class="line">976</span><br><span class="line">977</span><br><span class="line">978</span><br><span class="line">979</span><br><span class="line">980</span><br><span class="line">981</span><br><span class="line">982</span><br><span class="line">983</span><br><span class="line">984</span><br><span class="line">985</span><br><span class="line">986</span><br><span class="line">987</span><br><span class="line">988</span><br><span class="line">989</span><br><span class="line">990</span><br><span class="line">991</span><br><span class="line">992</span><br><span class="line">993</span><br><span class="line">994</span><br><span class="line">995</span><br><span class="line">996</span><br><span class="line">997</span><br><span class="line">998</span><br><span class="line">999</span><br><span class="line">1000</span><br><span class="line">1001</span><br><span class="line">1002</span><br><span class="line">1003</span><br><span class="line">1004</span><br><span class="line">1005</span><br><span class="line">1006</span><br><span class="line">1007</span><br><span class="line">1008</span><br><span class="line">1009</span><br><span class="line">1010</span><br><span class="line">1011</span><br><span class="line">1012</span><br><span class="line">1013</span><br><span class="line">1014</span><br><span class="line">1015</span><br><span class="line">1016</span><br><span class="line">1017</span><br><span class="line">1018</span><br><span class="line">1019</span><br><span class="line">1020</span><br><span class="line">1021</span><br><span class="line">1022</span><br><span class="line">1023</span><br><span class="line">1024</span><br><span class="line">1025</span><br><span class="line">1026</span><br><span class="line">1027</span><br><span class="line">1028</span><br><span class="line">1029</span><br><span class="line">1030</span><br><span class="line">1031</span><br><span class="line">1032</span><br><span class="line">1033</span><br><span class="line">1034</span><br><span class="line">1035</span><br><span class="line">1036</span><br><span class="line">1037</span><br><span class="line">1038</span><br><span class="line">1039</span><br><span class="line">1040</span><br><span class="line">1041</span><br><span class="line">1042</span><br><span class="line">1043</span><br><span class="line">1044</span><br><span class="line">1045</span><br><span class="line">1046</span><br><span class="line">1047</span><br><span class="line">1048</span><br><span class="line">1049</span><br><span class="line">1050</span><br><span class="line">1051</span><br><span class="line">1052</span><br><span class="line">1053</span><br><span class="line">1054</span><br><span class="line">1055</span><br><span class="line">1056</span><br><span class="line">1057</span><br><span class="line">1058</span><br><span class="line">1059</span><br><span class="line">1060</span><br><span class="line">1061</span><br><span class="line">1062</span><br><span class="line">1063</span><br><span class="line">1064</span><br><span class="line">1065</span><br><span class="line">1066</span><br><span class="line">1067</span><br><span class="line">1068</span><br><span class="line">1069</span><br><span class="line">1070</span><br><span class="line">1071</span><br><span class="line">1072</span><br><span class="line">1073</span><br><span class="line">1074</span><br><span class="line">1075</span><br><span class="line">1076</span><br><span class="line">1077</span><br><span class="line">1078</span><br><span class="line">1079</span><br><span class="line">1080</span><br><span class="line">1081</span><br><span class="line">1082</span><br><span class="line">1083</span><br><span class="line">1084</span><br><span class="line">1085</span><br><span class="line">1086</span><br><span class="line">1087</span><br><span class="line">1088</span><br><span class="line">1089</span><br><span class="line">1090</span><br><span class="line">1091</span><br><span class="line">1092</span><br><span class="line">1093</span><br><span class="line">1094</span><br><span class="line">1095</span><br><span class="line">1096</span><br><span class="line">1097</span><br><span class="line">1098</span><br><span class="line">1099</span><br><span class="line">1100</span><br><span class="line">1101</span><br><span class="line">1102</span><br><span class="line">1103</span><br><span class="line">1104</span><br><span class="line">1105</span><br><span class="line">1106</span><br><span class="line">1107</span><br><span class="line">1108</span><br><span class="line">1109</span><br><span class="line">1110</span><br><span class="line">1111</span><br><span class="line">1112</span><br><span class="line">1113</span><br><span class="line">1114</span><br><span class="line">1115</span><br><span class="line">1116</span><br><span class="line">1117</span><br><span class="line">1118</span><br><span class="line">1119</span><br><span class="line">1120</span><br><span class="line">1121</span><br><span class="line">1122</span><br><span class="line">1123</span><br><span class="line">1124</span><br><span class="line">1125</span><br><span class="line">1126</span><br><span class="line">1127</span><br><span class="line">1128</span><br><span class="line">1129</span><br><span class="line">1130</span><br><span class="line">1131</span><br><span class="line">1132</span><br><span class="line">1133</span><br><span class="line">1134</span><br><span class="line">1135</span><br><span class="line">1136</span><br><span class="line">1137</span><br><span class="line">1138</span><br><span class="line">1139</span><br><span class="line">1140</span><br><span class="line">1141</span><br><span class="line">1142</span><br><span class="line">1143</span><br><span class="line">1144</span><br><span class="line">1145</span><br><span class="line">1146</span><br><span class="line">1147</span><br><span class="line">1148</span><br><span class="line">1149</span><br><span class="line">1150</span><br><span class="line">1151</span><br><span class="line">1152</span><br><span class="line">1153</span><br><span class="line">1154</span><br><span class="line">1155</span><br><span class="line">1156</span><br><span class="line">1157</span><br><span class="line">1158</span><br><span class="line">1159</span><br><span class="line">1160</span><br><span class="line">1161</span><br><span class="line">1162</span><br><span class="line">1163</span><br><span class="line">1164</span><br><span class="line">1165</span><br><span class="line">1166</span><br><span class="line">1167</span><br><span class="line">1168</span><br><span class="line">1169</span><br><span class="line">1170</span><br><span class="line">1171</span><br><span class="line">1172</span><br><span class="line">1173</span><br><span class="line">1174</span><br><span class="line">1175</span><br><span class="line">1176</span><br><span class="line">1177</span><br><span class="line">1178</span><br><span class="line">1179</span><br><span class="line">1180</span><br><span class="line">1181</span><br><span class="line">1182</span><br><span class="line">1183</span><br><span class="line">1184</span><br><span class="line">1185</span><br><span class="line">1186</span><br><span class="line">1187</span><br><span class="line">1188</span><br><span class="line">1189</span><br><span class="line">1190</span><br><span class="line">1191</span><br><span class="line">1192</span><br><span class="line">1193</span><br><span class="line">1194</span><br><span class="line">1195</span><br><span class="line">1196</span><br><span class="line">1197</span><br><span class="line">1198</span><br><span class="line">1199</span><br><span class="line">1200</span><br><span class="line">1201</span><br><span class="line">1202</span><br><span class="line">1203</span><br><span class="line">1204</span><br><span class="line">1205</span><br><span class="line">1206</span><br><span class="line">1207</span><br><span class="line">1208</span><br><span class="line">1209</span><br><span class="line">1210</span><br><span class="line">1211</span><br><span class="line">1212</span><br><span class="line">1213</span><br><span class="line">1214</span><br><span class="line">1215</span><br><span class="line">1216</span><br><span class="line">1217</span><br><span class="line">1218</span><br><span class="line">1219</span><br><span class="line">1220</span><br><span class="line">1221</span><br><span class="line">1222</span><br><span class="line">1223</span><br><span class="line">1224</span><br><span class="line">1225</span><br><span class="line">1226</span><br><span class="line">1227</span><br><span class="line">1228</span><br><span class="line">1229</span><br><span class="line">1230</span><br><span class="line">1231</span><br><span class="line">1232</span><br><span class="line">1233</span><br><span class="line">1234</span><br><span class="line">1235</span><br><span class="line">1236</span><br><span class="line">1237</span><br><span class="line">1238</span><br><span class="line">1239</span><br><span class="line">1240</span><br><span class="line">1241</span><br><span class="line">1242</span><br><span class="line">1243</span><br><span class="line">1244</span><br><span class="line">1245</span><br><span class="line">1246</span><br><span class="line">1247</span><br><span class="line">1248</span><br><span class="line">1249</span><br><span class="line">1250</span><br><span class="line">1251</span><br><span class="line">1252</span><br><span class="line">1253</span><br><span class="line">1254</span><br><span class="line">1255</span><br><span class="line">1256</span><br><span class="line">1257</span><br><span class="line">1258</span><br><span class="line">1259</span><br><span class="line">1260</span><br><span class="line">1261</span><br><span class="line">1262</span><br><span class="line">1263</span><br><span class="line">1264</span><br><span class="line">1265</span><br><span class="line">1266</span><br><span class="line">1267</span><br><span class="line">1268</span><br><span class="line">1269</span><br><span class="line">1270</span><br><span class="line">1271</span><br><span class="line">1272</span><br><span class="line">1273</span><br><span class="line">1274</span><br><span class="line">1275</span><br><span class="line">1276</span><br><span class="line">1277</span><br><span class="line">1278</span><br><span class="line">1279</span><br><span class="line">1280</span><br><span class="line">1281</span><br><span class="line">1282</span><br><span class="line">1283</span><br><span class="line">1284</span><br><span class="line">1285</span><br><span class="line">1286</span><br><span class="line">1287</span><br><span class="line">1288</span><br><span class="line">1289</span><br><span class="line">1290</span><br><span class="line">1291</span><br><span class="line">1292</span><br><span class="line">1293</span><br><span class="line">1294</span><br><span class="line">1295</span><br><span class="line">1296</span><br><span class="line">1297</span><br><span class="line">1298</span><br><span class="line">1299</span><br><span class="line">1300</span><br><span class="line">1301</span><br><span class="line">1302</span><br><span class="line">1303</span><br><span class="line">1304</span><br><span class="line">1305</span><br><span class="line">1306</span><br><span class="line">1307</span><br><span class="line">1308</span><br><span class="line">1309</span><br><span class="line">1310</span><br><span class="line">1311</span><br><span class="line">1312</span><br><span class="line">1313</span><br><span class="line">1314</span><br><span class="line">1315</span><br><span class="line">1316</span><br><span class="line">1317</span><br><span class="line">1318</span><br><span class="line">1319</span><br><span class="line">1320</span><br><span class="line">1321</span><br><span class="line">1322</span><br><span class="line">1323</span><br><span class="line">1324</span><br><span class="line">1325</span><br><span class="line">1326</span><br><span class="line">1327</span><br><span class="line">1328</span><br><span class="line">1329</span><br><span class="line">1330</span><br><span class="line">1331</span><br><span class="line">1332</span><br><span class="line">1333</span><br><span class="line">1334</span><br><span class="line">1335</span><br><span class="line">1336</span><br><span class="line">1337</span><br><span class="line">1338</span><br><span class="line">1339</span><br><span class="line">1340</span><br><span class="line">1341</span><br><span class="line">1342</span><br><span class="line">1343</span><br><span class="line">1344</span><br><span class="line">1345</span><br><span class="line">1346</span><br><span class="line">1347</span><br><span class="line">1348</span><br><span class="line">1349</span><br><span class="line">1350</span><br><span class="line">1351</span><br><span class="line">1352</span><br><span class="line">1353</span><br><span class="line">1354</span><br><span class="line">1355</span><br><span class="line">1356</span><br><span class="line">1357</span><br><span class="line">1358</span><br><span class="line">1359</span><br><span class="line">1360</span><br><span class="line">1361</span><br><span class="line">1362</span><br><span class="line">1363</span><br><span class="line">1364</span><br><span class="line">1365</span><br><span class="line">1366</span><br><span class="line">1367</span><br><span class="line">1368</span><br><span class="line">1369</span><br><span class="line">1370</span><br><span class="line">1371</span><br><span class="line">1372</span><br><span class="line">1373</span><br><span class="line">1374</span><br><span class="line">1375</span><br><span class="line">1376</span><br><span class="line">1377</span><br><span class="line">1378</span><br><span class="line">1379</span><br><span class="line">1380</span><br><span class="line">1381</span><br><span class="line">1382</span><br><span class="line">1383</span><br><span class="line">1384</span><br><span class="line">1385</span><br><span class="line">1386</span><br><span class="line">1387</span><br><span class="line">1388</span><br><span class="line">1389</span><br><span class="line">1390</span><br><span class="line">1391</span><br><span class="line">1392</span><br><span class="line">1393</span><br><span class="line">1394</span><br><span class="line">1395</span><br><span class="line">1396</span><br><span class="line">1397</span><br><span class="line">1398</span><br><span class="line">1399</span><br><span class="line">1400</span><br><span class="line">1401</span><br><span class="line">1402</span><br><span class="line">1403</span><br><span class="line">1404</span><br><span class="line">1405</span><br><span class="line">1406</span><br><span class="line">1407</span><br><span class="line">1408</span><br><span class="line">1409</span><br><span class="line">1410</span><br><span class="line">1411</span><br><span class="line">1412</span><br><span class="line">1413</span><br><span class="line">1414</span><br><span class="line">1415</span><br><span class="line">1416</span><br><span class="line">1417</span><br><span class="line">1418</span><br><span class="line">1419</span><br><span class="line">1420</span><br><span class="line">1421</span><br><span class="line">1422</span><br><span class="line">1423</span><br><span class="line">1424</span><br><span class="line">1425</span><br><span class="line">1426</span><br><span class="line">1427</span><br><span class="line">1428</span><br><span class="line">1429</span><br><span class="line">1430</span><br><span class="line">1431</span><br><span class="line">1432</span><br><span class="line">1433</span><br><span class="line">1434</span><br><span class="line">1435</span><br><span class="line">1436</span><br><span class="line">1437</span><br><span class="line">1438</span><br><span class="line">1439</span><br><span class="line">1440</span><br><span class="line">1441</span><br><span class="line">1442</span><br><span class="line">1443</span><br><span class="line">1444</span><br><span class="line">1445</span><br><span class="line">1446</span><br><span class="line">1447</span><br><span class="line">1448</span><br><span class="line">1449</span><br><span class="line">1450</span><br><span class="line">1451</span><br><span class="line">1452</span><br><span class="line">1453</span><br><span class="line">1454</span><br><span class="line">1455</span><br><span class="line">1456</span><br><span class="line">1457</span><br><span class="line">1458</span><br><span class="line">1459</span><br><span class="line">1460</span><br><span class="line">1461</span><br><span class="line">1462</span><br><span class="line">1463</span><br><span class="line">1464</span><br><span class="line">1465</span><br><span class="line">1466</span><br><span class="line">1467</span><br><span class="line">1468</span><br><span class="line">1469</span><br><span class="line">1470</span><br><span class="line">1471</span><br><span class="line">1472</span><br><span class="line">1473</span><br><span class="line">1474</span><br><span class="line">1475</span><br><span class="line">1476</span><br><span class="line">1477</span><br><span class="line">1478</span><br><span class="line">1479</span><br><span class="line">1480</span><br><span class="line">1481</span><br><span class="line">1482</span><br><span class="line">1483</span><br><span class="line">1484</span><br><span class="line">1485</span><br><span class="line">1486</span><br><span class="line">1487</span><br><span class="line">1488</span><br><span class="line">1489</span><br><span class="line">1490</span><br><span class="line">1491</span><br><span class="line">1492</span><br><span class="line">1493</span><br><span class="line">1494</span><br><span class="line">1495</span><br><span class="line">1496</span><br><span class="line">1497</span><br><span class="line">1498</span><br><span class="line">1499</span><br><span class="line">1500</span><br><span class="line">1501</span><br><span class="line">1502</span><br><span class="line">1503</span><br><span class="line">1504</span><br><span class="line">1505</span><br><span class="line">1506</span><br><span class="line">1507</span><br><span class="line">1508</span><br><span class="line">1509</span><br><span class="line">1510</span><br></pre></td><td class="code"><pre><span class="line">Java 基础G</span><br><span class="line"></span><br><span class="line">1. JDK 和 JRE 有什么区别？</span><br><span class="line"></span><br><span class="line">JDK：Java Development Kit 的简称，Java 开发工具包，提供了 Java 的开发环境和运行环境。</span><br><span class="line">JRE：Java Runtime Environment 的简称，Java 运行环境，为 Java 的运行提供了所需环境。</span><br><span class="line">具体来说 JDK 其实包含了 JRE，同时还包含了编译 Java 源码的编译器 Javac，还包含了很多 Java 程序调试和分析的工具。简单来说：如果你需要运行 Java 程序，只需安装 JRE 就可以了，如果你需要编写 Java 程序，需要安装 JDK。</span><br><span class="line"></span><br><span class="line">2. == 和 equals 的区别是什么？</span><br><span class="line"></span><br><span class="line">== 解读</span><br><span class="line"></span><br><span class="line">对于基本类型和引用类型 == 的作用效果是不同的，如下所示：</span><br><span class="line"></span><br><span class="line">基本类型：比较的是值是否相同；</span><br><span class="line">引用类型：比较的是引用是否相同；</span><br><span class="line">代码示例：</span><br><span class="line"></span><br><span class="line">String x = &quot;string&quot;;</span><br><span class="line">String y = &quot;string&quot;;</span><br><span class="line">String z = new String(&quot;string&quot;);</span><br><span class="line">System.out.println(x==y); // true</span><br><span class="line">System.out.println(x==z); // false</span><br><span class="line">System.out.println(x.equals(y)); // true</span><br><span class="line">System.out.println(x.equals(z)); // true</span><br><span class="line">代码解读：因为 x 和 y 指向的是同一个引用，所以 == 也是 true，而 new String()方法则重写开辟了内存空间，所以 == 结果为 false，而 equals 比较的一直是值，所以结果都为 true。</span><br><span class="line"></span><br><span class="line">equals 解读</span><br><span class="line"></span><br><span class="line">equals 本质上就是 ==，只不过 String 和 Integer 等重写了 equals 方法，把它变成了值比较。看下面的代码就明白了。</span><br><span class="line"></span><br><span class="line">首先来看默认情况下 equals 比较一个有相同值的对象，代码如下：</span><br><span class="line"></span><br><span class="line">class Cat &#123;</span><br><span class="line">    public Cat(String name) &#123;</span><br><span class="line">        this.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    private String name;</span><br><span class="line"></span><br><span class="line">    public String getName() &#123;</span><br><span class="line">        return name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    public void setName(String name) &#123;</span><br><span class="line">        this.name = name;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Cat c1 = new Cat(&quot;tt&quot;);</span><br><span class="line">Cat c2 = new Cat(&quot;tt&quot;);</span><br><span class="line">System.out.println(c1.equals(c2)); // false</span><br><span class="line">输出结果出乎我们的意料，竟然是 false？这是怎么回事，看了 equals 源码就知道了，源码如下：</span><br><span class="line"></span><br><span class="line">public boolean equals(Object obj) &#123;</span><br><span class="line">        return (this == obj);</span><br><span class="line">&#125;</span><br><span class="line">原来 equals 本质上就是 ==。</span><br><span class="line"></span><br><span class="line">那问题来了，两个相同值的 String 对象，为什么返回的是 true？代码如下：</span><br><span class="line"></span><br><span class="line">String s1 = new String(&quot;老王&quot;);</span><br><span class="line">String s2 = new String(&quot;老王&quot;);</span><br><span class="line">System.out.println(s1.equals(s2)); // true</span><br><span class="line">同样的，当我们进入 String 的 equals 方法，找到了答案，代码如下：</span><br><span class="line"></span><br><span class="line">public boolean equals(Object anObject) &#123;</span><br><span class="line">    if (this == anObject) &#123;</span><br><span class="line">        return true;</span><br><span class="line">    &#125;</span><br><span class="line">    if (anObject instanceof String) &#123;</span><br><span class="line">        String anotherString = (String)anObject;</span><br><span class="line">        int n = value.length;</span><br><span class="line">        if (n == anotherString.value.length) &#123;</span><br><span class="line">            char v1[] = value;</span><br><span class="line">            char v2[] = anotherString.value;</span><br><span class="line">            int i = 0;</span><br><span class="line">            while (n-- != 0) &#123;</span><br><span class="line">                if (v1[i] != v2[i])</span><br><span class="line">                    return false;</span><br><span class="line">                i++;</span><br><span class="line">            &#125;</span><br><span class="line">            return true;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    return false;</span><br><span class="line">&#125;</span><br><span class="line">原来是 String 重写了 Object 的 equals 方法，把引用比较改成了值比较。</span><br><span class="line"></span><br><span class="line">总结 ：== 对于基本类型来说是值比较，对于引用类型来说是比较的是引用；而 equals 默认情况下是引用比较，只是很多类重新了 equals 方法，比如 String、Integer 等把它变成了值比较，所以一般情况下 equals 比较的是值是否相等。</span><br><span class="line"></span><br><span class="line">3. 两个对象的 hashCode() 相同，则 equals() 也一定为 true，对吗？</span><br><span class="line"></span><br><span class="line">不对，两个对象的 hashCode() 相同，equals() 不一定 true。</span><br><span class="line"></span><br><span class="line">代码示例：</span><br><span class="line"></span><br><span class="line">String str1 = &quot;通话&quot;;</span><br><span class="line">String str2 = &quot;重地&quot;;</span><br><span class="line">System. out. println(String. format(&quot;str1：%d | str2：%d&quot;,  str1. hashCode(),str2. hashCode()));</span><br><span class="line">System. out. println(str1. equals(str2));</span><br><span class="line">执行的结果：</span><br><span class="line"></span><br><span class="line">str1：1179395 | str2：1179395</span><br><span class="line"></span><br><span class="line">false</span><br><span class="line">代码解读：很显然“通话”和“重地”的 hashCode() 相同，然而 equals() 则为 false，因为在散列表中，hashCode() 相等即两个键值对的哈希值相等，然而哈希值相等，并不一定能得出键值对相等。</span><br><span class="line"></span><br><span class="line">4. final 在 Java 中有什么作用？</span><br><span class="line"></span><br><span class="line">final 修饰的类叫最终类，该类不能被继承。</span><br><span class="line">final 修饰的方法不能被重写。</span><br><span class="line">final 修饰的变量叫常量，常量必须初始化，初始化之后值就不能被修改。</span><br><span class="line">5. Java 中的 Math. round(-1. 5) 等于多少？</span><br><span class="line"></span><br><span class="line">等于 -1，因为在数轴上取值时，中间值（0.5）向右取整，所以正 0.5 是往上取整，负 0.5 是直接舍弃。</span><br><span class="line"></span><br><span class="line">6. String 属于基础的数据类型吗？</span><br><span class="line"></span><br><span class="line">String 不属于基础类型，基础类型有 8 种：byte、boolean、char、short、int、float、long、double，而 String 属于对象。</span><br><span class="line"></span><br><span class="line">7. Java 中操作字符串都有哪些类？它们之间有什么区别？</span><br><span class="line"></span><br><span class="line">操作字符串的类有：String、StringBuffer、StringBuilder。</span><br><span class="line"></span><br><span class="line">String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象，每次操作都会生成新的 String 对象，然后将指针指向新的 String 对象，而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作，所以在经常改变字符串内容的情况下最好不要使用 String。</span><br><span class="line"></span><br><span class="line">StringBuffer 和 StringBuilder 最大的区别在于，StringBuffer 是线程安全的，而 StringBuilder 是非线程安全的，但 StringBuilder 的性能却高于 StringBuffer，所以在单线程环境下推荐使用 StringBuilder，多线程环境下推荐使用 StringBuffer。</span><br><span class="line"></span><br><span class="line">8. String str=&quot;i&quot;与 String str=new String(&quot;i&quot;)一样吗？</span><br><span class="line"></span><br><span class="line">不一样，因为内存的分配方式不一样。String str=&quot;i&quot;的方式，Java 虚拟机会将其分配到常量池中；而 String str=new String(&quot;i&quot;) 则会被分到堆内存中。</span><br><span class="line"></span><br><span class="line">9. 如何将字符串反转？</span><br><span class="line"></span><br><span class="line">使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。</span><br><span class="line"></span><br><span class="line">示例代码：</span><br><span class="line"></span><br><span class="line">// StringBuffer reverse</span><br><span class="line">StringBuffer stringBuffer = new StringBuffer();</span><br><span class="line">stringBuffer. append(&quot;abcdefg&quot;);</span><br><span class="line">System. out. println(stringBuffer. reverse()); // gfedcba</span><br><span class="line">// StringBuilder reverse</span><br><span class="line">StringBuilder stringBuilder = new StringBuilder();</span><br><span class="line">stringBuilder. append(&quot;abcdefg&quot;);</span><br><span class="line">System. out. println(stringBuilder. reverse()); // gfedcba</span><br><span class="line">10. String 类的常用方法都有那些？</span><br><span class="line"></span><br><span class="line">indexOf()：返回指定字符的索引。</span><br><span class="line">charAt()：返回指定索引处的字符。</span><br><span class="line">replace()：字符串替换。</span><br><span class="line">trim()：去除字符串两端空白。</span><br><span class="line">split()：分割字符串，返回一个分割后的字符串数组。</span><br><span class="line">getBytes()：返回字符串的 byte 类型数组。</span><br><span class="line">length()：返回字符串长度。</span><br><span class="line">toLowerCase()：将字符串转成小写字母。</span><br><span class="line">toUpperCase()：将字符串转成大写字符。</span><br><span class="line">substring()：截取字符串。</span><br><span class="line">equals()：字符串比较。</span><br><span class="line">11. 抽象类必须要有抽象方法吗？</span><br><span class="line"></span><br><span class="line">不需要，抽象类不一定非要有抽象方法。</span><br><span class="line"></span><br><span class="line">示例代码：</span><br><span class="line"></span><br><span class="line">abstract class Cat &#123;</span><br><span class="line">    public static void sayHi() &#123;</span><br><span class="line">        System. out. println(&quot;hi~&quot;);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line">上面代码，抽象类并没有抽象方法但完全可以正常运行。</span><br><span class="line"></span><br><span class="line">12. 普通类和抽象类有哪些区别？</span><br><span class="line"></span><br><span class="line">普通类不能包含抽象方法，抽象类可以包含抽象方法。</span><br><span class="line">抽象类不能直接实例化，普通类可以直接实例化。</span><br><span class="line">13. 抽象类能使用 final 修饰吗？</span><br><span class="line"></span><br><span class="line">不能，定义抽象类就是让其他类继承的，如果定义为 final 该类就不能被继承，这样彼此就会产生矛盾，所以 final 不能修饰抽象类，如下图所示，编辑器也会提示错误信息：</span><br><span class="line"></span><br><span class="line">编译器保存图</span><br><span class="line"></span><br><span class="line">14. 接口和抽象类有什么区别？</span><br><span class="line"></span><br><span class="line">实现：抽象类的子类使用 extends 来继承；接口必须使用 implements 来实现接口。</span><br><span class="line">构造函数：抽象类可以有构造函数；接口不能有。</span><br><span class="line">实现数量：类可以实现很多个接口；但是只能继承一个抽象类。</span><br><span class="line">访问修饰符：接口中的方法默认使用 public 修饰；抽象类中的方法可以是任意访问修饰符。</span><br><span class="line">15. Java 中 IO 流分为几种？</span><br><span class="line"></span><br><span class="line">按功能来分：输入流（input）、输出流（output）。</span><br><span class="line"></span><br><span class="line">按类型来分：字节流和字符流。</span><br><span class="line"></span><br><span class="line">字节流和字符流的区别是：字节流按 8 位传输以字节为单位输入输出数据，字符流按 16 位传输以字符为单位输入输出数据。</span><br><span class="line"></span><br><span class="line">16. BIO、NIO、AIO 有什么区别？</span><br><span class="line"></span><br><span class="line">BIO：Block IO 同步阻塞式 IO，就是我们平常使用的传统 IO，它的特点是模式简单使用方便，并发处理能力低。</span><br><span class="line">NIO：Non IO 同步非阻塞 IO，是传统 IO 的升级，客户端和服务器端通过 Channel（通道）通讯，实现了多路复用。</span><br><span class="line">AIO：Asynchronous IO 是 NIO 的升级，也叫 NIO2，实现了异步非堵塞 IO ，异步 IO 的操作基于事件和回调机制。</span><br><span class="line">17. Files的常用方法都有哪些？</span><br><span class="line"></span><br><span class="line">Files. exists()：检测文件路径是否存在。</span><br><span class="line">Files. createFile()：创建文件。</span><br><span class="line">Files. createDirectory()：创建文件夹。</span><br><span class="line">Files. delete()：删除一个文件或目录。</span><br><span class="line">Files. copy()：复制文件。</span><br><span class="line">Files. move()：移动文件。</span><br><span class="line">Files. size()：查看文件个数。</span><br><span class="line">Files. read()：读取文件。</span><br><span class="line">Files. write()：写入文件。</span><br><span class="line">容器</span><br><span class="line"></span><br><span class="line">18. Java 容器都有哪些？</span><br><span class="line"></span><br><span class="line">Java 容器分为 Collection 和 Map 两大类，其下又有很多子类，如下所示：</span><br><span class="line"></span><br><span class="line">Collection</span><br><span class="line">List</span><br><span class="line">ArrayList</span><br><span class="line">LinkedList</span><br><span class="line">Vector</span><br><span class="line">Stack</span><br><span class="line">Set</span><br><span class="line">HashSet</span><br><span class="line">LinkedHashSet</span><br><span class="line">TreeSet</span><br><span class="line">Map</span><br><span class="line">HashMap</span><br><span class="line">LinkedHashMap</span><br><span class="line">TreeMap</span><br><span class="line">ConcurrentHashMap</span><br><span class="line">Hashtable</span><br><span class="line">19. Collection 和 Collections 有什么区别？</span><br><span class="line"></span><br><span class="line">Collection 是一个集合接口，它提供了对集合对象进行基本操作的通用接口方法，所有集合都是它的子类，比如 List、Set 等。</span><br><span class="line">Collections 是一个包装类，包含了很多静态方法，不能被实例化，就像一个工具类，比如提供的排序方法： Collections. sort(list)。</span><br><span class="line">20. List、Set、Map 之间的区别是什么？</span><br><span class="line"></span><br><span class="line">List、Set、Map 的区别主要体现在两个方面：元素是否有序、是否允许元素重复。</span><br><span class="line"></span><br><span class="line">三者之间的区别，如下表：</span><br><span class="line"></span><br><span class="line">区别图</span><br><span class="line"></span><br><span class="line">21. HashMap 和 Hashtable 有什么区别？</span><br><span class="line"></span><br><span class="line">存储：HashMap 运行 key 和 value 为 null，而 Hashtable 不允许。</span><br><span class="line">线程安全：Hashtable 是线程安全的，而 HashMap 是非线程安全的。</span><br><span class="line">推荐使用：在 Hashtable 的类注释可以看到，Hashtable 是保留类不建议使用，推荐在单线程环境下使用 HashMap 替代，如果需要多线程使用则用 ConcurrentHashMap 替代。</span><br><span class="line">22. 如何决定使用 HashMap 还是 TreeMap？</span><br><span class="line"></span><br><span class="line">对于在 Map 中插入、删除、定位一个元素这类操作，HashMap 是最好的选择，因为相对而言 HashMap 的插入会更快，但如果你要对一个 key 集合进行有序的遍历，那 TreeMap 是更好的选择。</span><br><span class="line"></span><br><span class="line">23. 说一下 HashMap 的实现原理？</span><br><span class="line"></span><br><span class="line">HashMap 基于 Hash 算法实现的，我们通过 put(key,value)存储，get(key)来获取。当传入 key 时，HashMap 会根据 key. hashCode() 计算出 hash 值，根据 hash 值将 value 保存在 bucket 里。当计算出的 hash 值相同时，我们称之为 hash 冲突，HashMap 的做法是用链表和红黑树存储相同 hash 值的 value。当 hash 冲突的个数比较少时，使用链表否则使用红黑树。</span><br><span class="line"></span><br><span class="line">24. 说一下 HashSet 的实现原理？</span><br><span class="line"></span><br><span class="line">HashSet 是基于 HashMap 实现的，HashSet 底层使用 HashMap 来保存所有元素，因此 HashSet 的实现比较简单，相关 HashSet 的操作，基本上都是直接调用底层 HashMap 的相关方法来完成，HashSet 不允许重复的值。</span><br><span class="line"></span><br><span class="line">25. ArrayList 和 LinkedList 的区别是什么？</span><br><span class="line"></span><br><span class="line">数据结构实现：ArrayList 是动态数组的数据结构实现，而 LinkedList 是双向链表的数据结构实现。</span><br><span class="line">随机访问效率：ArrayList 比 LinkedList 在随机访问的时候效率要高，因为 LinkedList 是线性的数据存储方式，所以需要移动指针从前往后依次查找。</span><br><span class="line">增加和删除效率：在非首尾的增加和删除操作，LinkedList 要比 ArrayList 效率要高，因为 ArrayList 增删操作要影响数组内的其他数据的下标。</span><br><span class="line">综合来说，在需要频繁读取集合中的元素时，更推荐使用 ArrayList，而在插入和删除操作较多时，更推荐使用 LinkedList。</span><br><span class="line"></span><br><span class="line">26. 如何实现数组和 List 之间的转换？</span><br><span class="line"></span><br><span class="line">数组转 List：使用 Arrays. asList(array) 进行转换。</span><br><span class="line">List 转数组：使用 List 自带的 toArray() 方法。</span><br><span class="line">代码示例：</span><br><span class="line"></span><br><span class="line">// list to array</span><br><span class="line">List&lt;String&gt; list = new ArrayList&lt;String&gt;();</span><br><span class="line">list. add(&quot;tt&quot;);</span><br><span class="line">list. add(&quot;的博客&quot;);</span><br><span class="line">list. toArray();</span><br><span class="line">// array to list</span><br><span class="line">String[] array = new String[]&#123;&quot;tt&quot;,&quot;的博客&quot;&#125;;</span><br><span class="line">Arrays. asList(array);</span><br><span class="line">27. ArrayList 和 Vector 的区别是什么？</span><br><span class="line"></span><br><span class="line">线程安全：Vector 使用了 Synchronized 来实现线程同步，是线程安全的，而 ArrayList 是非线程安全的。</span><br><span class="line">性能：ArrayList 在性能方面要优于 Vector。</span><br><span class="line">扩容：ArrayList 和 Vector 都会根据实际的需要动态的调整容量，只不过在 Vector 扩容每次会增加 1 倍，而 ArrayList 只会增加 50%。</span><br><span class="line">28. Array 和 ArrayList 有何区别？</span><br><span class="line"></span><br><span class="line">Array 可以存储基本数据类型和对象，ArrayList 只能存储对象。</span><br><span class="line">Array 是指定固定大小的，而 ArrayList 大小是自动扩展的。</span><br><span class="line">Array 内置方法没有 ArrayList 多，比如 addAll、removeAll、iteration 等方法只有 ArrayList 有。</span><br><span class="line">29. 在 Queue 中 poll()和 remove()有什么区别？</span><br><span class="line"></span><br><span class="line">相同点：都是返回第一个元素，并在队列中删除返回的对象。</span><br><span class="line">不同点：如果没有元素 poll()会返回 null，而 remove()会直接抛出 NoSuchElementException 异常。</span><br><span class="line">代码示例：</span><br><span class="line"></span><br><span class="line">Queue&lt;String&gt; queue = new LinkedList&lt;String&gt;();</span><br><span class="line">queue. offer(&quot;string&quot;); // add</span><br><span class="line">System. out. println(queue. poll());</span><br><span class="line">System. out. println(queue. remove());</span><br><span class="line">System. out. println(queue. size());</span><br><span class="line">30. 哪些集合类是线程安全的？</span><br><span class="line"></span><br><span class="line">Vector、Hashtable、Stack 都是线程安全的，而像 HashMap 则是非线程安全的，不过在 JDK 1.5 之后随着 Java. util. concurrent 并发包的出现，它们也有了自己对应的线程安全类，比如 HashMap 对应的线程安全类就是 ConcurrentHashMap。</span><br><span class="line"></span><br><span class="line">31. 迭代器 Iterator 是什么？</span><br><span class="line"></span><br><span class="line">Iterator 接口提供遍历任何 Collection 的接口。我们可以从一个 Collection 中使用迭代器方法来获取迭代器实例。迭代器取代了 Java 集合框架中的 Enumeration，迭代器允许调用者在迭代过程中移除元素。</span><br><span class="line"></span><br><span class="line">32. Iterator 怎么使用？有什么特点？</span><br><span class="line"></span><br><span class="line">Iterator 使用代码如下：</span><br><span class="line"></span><br><span class="line">List&lt;String&gt; list = new ArrayList&lt;&gt;();</span><br><span class="line">Iterator&lt;String&gt; it = list. iterator();</span><br><span class="line">while(it. hasNext())&#123;</span><br><span class="line">  String obj = it. next();</span><br><span class="line">  System. out. println(obj);</span><br><span class="line">&#125;</span><br><span class="line">Iterator 的特点是更加安全，因为它可以确保，在当前遍历的集合元素被更改的时候，就会抛出 ConcurrentModificationException 异常。</span><br><span class="line"></span><br><span class="line">33. Iterator 和 ListIterator 有什么区别？</span><br><span class="line"></span><br><span class="line">Iterator 可以遍历 Set 和 List 集合，而 ListIterator 只能遍历 List。</span><br><span class="line">Iterator 只能单向遍历，而 ListIterator 可以双向遍历（向前/后遍历）。</span><br><span class="line">ListIterator 从 Iterator 接口继承，然后添加了一些额外的功能，比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。</span><br><span class="line">34. 怎么确保一个集合不能被修改？</span><br><span class="line"></span><br><span class="line">可以使用 Collections. unmodifiableCollection(Collection c) 方法来创建一个只读集合，这样改变集合的任何操作都会抛出 Java. lang. UnsupportedOperationException 异常。</span><br><span class="line"></span><br><span class="line">示例代码如下：</span><br><span class="line"></span><br><span class="line">List&lt;String&gt; list = new ArrayList&lt;&gt;();</span><br><span class="line">list. add(&quot;x&quot;);</span><br><span class="line">Collection&lt;String&gt; clist = Collections. unmodifiableCollection(list);</span><br><span class="line">clist. add(&quot;y&quot;); // 运行时此行报错</span><br><span class="line">System. out. println(list. size());</span><br><span class="line">多线程</span><br><span class="line"></span><br><span class="line">35. 并行和并发有什么区别？</span><br><span class="line"></span><br><span class="line">并行：多个处理器或多核处理器同时处理多个任务。</span><br><span class="line">并发：多个任务在同一个 CPU 核上，按细分的时间片轮流(交替)执行，从逻辑上来看那些任务是同时执行。</span><br><span class="line">如下图：</span><br><span class="line"></span><br><span class="line">并发和并行</span><br><span class="line"></span><br><span class="line">并发 = 两个队列和一台咖啡机。</span><br><span class="line"></span><br><span class="line">并行 = 两个队列和两台咖啡机。</span><br><span class="line"></span><br><span class="line">36. 线程和进程的区别？</span><br><span class="line"></span><br><span class="line">一个程序下至少有一个进程，一个进程下至少有一个线程，一个进程下也可以有多个线程来增加程序的执行速度。</span><br><span class="line"></span><br><span class="line">37. 守护线程是什么？</span><br><span class="line"></span><br><span class="line">守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。</span><br><span class="line"></span><br><span class="line">38. 创建线程有哪几种方式？</span><br><span class="line"></span><br><span class="line">创建线程有三种方式：</span><br><span class="line"></span><br><span class="line">继承 Thread 重写 run 方法；</span><br><span class="line">实现 Runnable 接口；</span><br><span class="line">实现 Callable 接口。</span><br><span class="line">39. 说一下 runnable 和 callable 有什么区别？</span><br><span class="line"></span><br><span class="line">runnable 没有返回值，callable 可以拿到有返回值，callable 可以看作是 runnable 的补充。</span><br><span class="line"></span><br><span class="line">40. 线程有哪些状态？</span><br><span class="line"></span><br><span class="line">线程的状态：</span><br><span class="line"></span><br><span class="line">NEW 尚未启动</span><br><span class="line">RUNNABLE 正在执行中</span><br><span class="line">BLOCKED 阻塞的（被同步锁或者IO锁阻塞）</span><br><span class="line">WAITING 永久等待状态</span><br><span class="line">TIMED_WAITING 等待指定的时间重新被唤醒的状态</span><br><span class="line">TERMINATED 执行完成</span><br><span class="line">41. sleep() 和 wait() 有什么区别？</span><br><span class="line"></span><br><span class="line">类的不同：sleep() 来自 Thread，wait() 来自 Object。</span><br><span class="line">释放锁：sleep() 不释放锁；wait() 释放锁。</span><br><span class="line">用法不同：sleep() 时间到会自动恢复；wait() 可以使用 notify()/notifyAll()直接唤醒。</span><br><span class="line">42. notify()和 notifyAll()有什么区别？</span><br><span class="line"></span><br><span class="line">notifyAll()会唤醒所有的线程，notify()之后唤醒一个线程。notifyAll() 调用后，会将全部线程由等待池移到锁池，然后参与锁的竞争，竞争成功则继续执行，如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程，具体唤醒哪一个线程由虚拟机控制。</span><br><span class="line"></span><br><span class="line">43. 线程的 run() 和 start() 有什么区别？</span><br><span class="line"></span><br><span class="line">start() 方法用于启动线程，run() 方法用于执行线程的运行时代码。run() 可以重复调用，而 start() 只能调用一次。</span><br><span class="line"></span><br><span class="line">44. 创建线程池有哪几种方式？</span><br><span class="line"></span><br><span class="line">线程池创建有七种方式，最核心的是最后一种：</span><br><span class="line"></span><br><span class="line">newSingleThreadExecutor()：它的特点在于工作线程数目被限制为 1，操作一个无界的工作队列，所以它保证了所有任务的都是被顺序执行，最多会有一个任务处于活动状态，并且不允许使用者改动线程池实例，因此可以避免其改变线程数目；</span><br><span class="line"></span><br><span class="line">newCachedThreadPool()：它是一种用来处理大量短时间工作任务的线程池，具有几个鲜明特点：它会试图缓存线程并重用，当无缓存线程可用时，就会创建新的工作线程；如果线程闲置的时间超过 60 秒，则被终止并移出缓存；长时间闲置时，这种线程池，不会消耗什么资源。其内部使用 SynchronousQueue 作为工作队列；</span><br><span class="line"></span><br><span class="line">newFixedThreadPool(int nThreads)：重用指定数目（nThreads）的线程，其背后使用的是无界的工作队列，任何时候最多有 nThreads 个工作线程是活动的。这意味着，如果任务数量超过了活动队列数目，将在工作队列中等待空闲线程出现；如果有工作线程退出，将会有新的工作线程被创建，以补足指定的数目 nThreads；</span><br><span class="line"></span><br><span class="line">newSingleThreadScheduledExecutor()：创建单线程池，返回 ScheduledExecutorService，可以进行定时或周期性的工作调度；</span><br><span class="line"></span><br><span class="line">newScheduledThreadPool(int corePoolSize)：和newSingleThreadScheduledExecutor()类似，创建的是个 ScheduledExecutorService，可以进行定时或周期性的工作调度，区别在于单一工作线程还是多个工作线程；</span><br><span class="line"></span><br><span class="line">newWorkStealingPool(int parallelism)：这是一个经常被人忽略的线程池，Java 8 才加入这个创建方法，其内部会构建ForkJoinPool，利用Work-Stealing算法，并行地处理任务，不保证处理顺序；</span><br><span class="line"></span><br><span class="line">ThreadPoolExecutor()：是最原始的线程池创建，上面1-3创建方式都是对ThreadPoolExecutor的封装。</span><br><span class="line"></span><br><span class="line">45. 线程池都有哪些状态？</span><br><span class="line"></span><br><span class="line">RUNNING：这是最正常的状态，接受新的任务，处理等待队列中的任务。</span><br><span class="line">SHUTDOWN：不接受新的任务提交，但是会继续处理等待队列中的任务。</span><br><span class="line">STOP：不接受新的任务提交，不再处理等待队列中的任务，中断正在执行任务的线程。</span><br><span class="line">TIDYING：所有的任务都销毁了，workCount 为 0，线程池的状态在转换为 TIDYING 状态时，会执行钩子方法 terminated()。</span><br><span class="line">TERMINATED：terminated()方法结束后，线程池的状态就会变成这个。</span><br><span class="line">46. 线程池中 submit() 和 execute() 方法有什么区别？</span><br><span class="line"></span><br><span class="line">execute()：只能执行 Runnable 类型的任务。</span><br><span class="line">submit()：可以执行 Runnable 和 Callable 类型的任务。</span><br><span class="line">Callable 类型的任务可以获取执行的返回值，而 Runnable 执行无返回值。</span><br><span class="line"></span><br><span class="line">47. 在 Java 程序中怎么保证多线程的运行安全？</span><br><span class="line"></span><br><span class="line">方法一：使用安全类，比如 Java. util. concurrent 下的类。</span><br><span class="line">方法二：使用自动锁 synchronized。</span><br><span class="line">方法三：使用手动锁 Lock。</span><br><span class="line">手动锁 Java 示例代码如下：</span><br><span class="line"></span><br><span class="line">Lock lock = new ReentrantLock();</span><br><span class="line">lock. lock();</span><br><span class="line">try &#123;</span><br><span class="line">    System. out. println(&quot;获得锁&quot;);</span><br><span class="line">&#125; catch (Exception e) &#123;</span><br><span class="line">    // TODO: handle exception</span><br><span class="line">&#125; finally &#123;</span><br><span class="line">    System. out. println(&quot;释放锁&quot;);</span><br><span class="line">    lock. unlock();</span><br><span class="line">&#125;</span><br><span class="line">48. 多线程中 synchronized 锁升级的原理是什么？</span><br><span class="line"></span><br><span class="line">synchronized 锁升级原理：在锁对象的对象头里面有一个 threadid 字段，在第一次访问的时候 threadid 为空，jvm 让其持有偏向锁，并将 threadid 设置为其线程 id，再次进入的时候会先判断 threadid 是否与其线程 id 一致，如果一致则可以直接使用此对象，如果不一致，则升级偏向锁为轻量级锁，通过自旋循环一定次数来获取锁，执行一定次数之后，如果还没有正常获取到要使用的对象，此时就会把锁从轻量级升级为重量级锁，此过程就构成了 synchronized 锁的升级。</span><br><span class="line"></span><br><span class="line">锁的升级的目的：锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式，使用了偏向锁升级为轻量级锁再升级到重量级锁的方式，从而减低了锁带来的性能消耗。</span><br><span class="line"></span><br><span class="line">49. 什么是死锁？</span><br><span class="line"></span><br><span class="line">当线程 A 持有独占锁a，并尝试去获取独占锁 b 的同时，线程 B 持有独占锁 b，并尝试获取独占锁 a 的情况下，就会发生 AB 两个线程由于互相持有对方需要的锁，而发生的阻塞现象，我们称为死锁。</span><br><span class="line"></span><br><span class="line">50. 怎么防止死锁？</span><br><span class="line"></span><br><span class="line">尽量使用 tryLock(long timeout, TimeUnit unit)的方法(ReentrantLock、ReentrantReadWriteLock)，设置超时时间，超时可以退出防止死锁。</span><br><span class="line">尽量使用 Java. util. concurrent 并发类代替自己手写锁。</span><br><span class="line">尽量降低锁的使用粒度，尽量不要几个功能用同一把锁。</span><br><span class="line">尽量减少同步的代码块。</span><br><span class="line">51. ThreadLocal 是什么？有哪些使用场景？</span><br><span class="line"></span><br><span class="line">ThreadLocal 为每个使用该变量的线程提供独立的变量副本，所以每一个线程都可以独立地改变自己的副本，而不会影响其它线程所对应的副本。</span><br><span class="line"></span><br><span class="line">ThreadLocal 的经典使用场景是数据库连接和 session 管理等。</span><br><span class="line"></span><br><span class="line">52. 说一下 synchronized 底层实现原理？</span><br><span class="line"></span><br><span class="line">synchronized 是由一对 monitorenter/monitorexit 指令实现的，monitor 对象是同步的基本实现单元。在 Java 6 之前，monitor 的实现完全是依靠操作系统内部的互斥锁，因为需要进行用户态到内核态的切换，所以同步操作是一个无差别的重量级操作，性能也很低。但在 Java 6 的时候，Java 虚拟机 对此进行了大刀阔斧地改进，提供了三种不同的 monitor 实现，也就是常说的三种不同的锁：偏向锁（Biased Locking）、轻量级锁和重量级锁，大大改进了其性能。</span><br><span class="line"></span><br><span class="line">53. synchronized 和 volatile 的区别是什么？</span><br><span class="line"></span><br><span class="line">volatile 是变量修饰符；synchronized 是修饰类、方法、代码段。</span><br><span class="line">volatile 仅能实现变量的修改可见性，不能保证原子性；而 synchronized 则可以保证变量的修改可见性和原子性。</span><br><span class="line">volatile 不会造成线程的阻塞；synchronized 可能会造成线程的阻塞。</span><br><span class="line">54. synchronized 和 Lock 有什么区别？</span><br><span class="line"></span><br><span class="line">synchronized 可以给类、方法、代码块加锁；而 lock 只能给代码块加锁。</span><br><span class="line">synchronized 不需要手动获取锁和释放锁，使用简单，发生异常会自动释放锁，不会造成死锁；而 lock 需要自己加锁和释放锁，如果使用不当没有 unLock()去释放锁就会造成死锁。</span><br><span class="line">通过 Lock 可以知道有没有成功获取锁，而 synchronized 却无法办到。</span><br><span class="line">55. synchronized 和 ReentrantLock 区别是什么？</span><br><span class="line"></span><br><span class="line">synchronized 早期的实现比较低效，对比 ReentrantLock，大多数场景性能都相差较大，但是在 Java 6 中对 synchronized 进行了非常多的改进。</span><br><span class="line"></span><br><span class="line">主要区别如下：</span><br><span class="line"></span><br><span class="line">ReentrantLock 使用起来比较灵活，但是必须有释放锁的配合动作；</span><br><span class="line">ReentrantLock 必须手动获取与释放锁，而 synchronized 不需要手动释放和开启锁；</span><br><span class="line">ReentrantLock 只适用于代码块锁，而 synchronized 可用于修饰方法、代码块等。</span><br><span class="line">volatile 标记的变量不会被编译器优化；synchronized 标记的变量可以被编译器优化。</span><br><span class="line">56. 说一下 atomic 的原理？</span><br><span class="line"></span><br><span class="line">atomic 主要利用 CAS (Compare And Wwap) 和 volatile 和 native 方法来保证原子操作，从而避免 synchronized 的高开销，执行效率大为提升。</span><br><span class="line"></span><br><span class="line">反射</span><br><span class="line"></span><br><span class="line">57. 什么是反射？</span><br><span class="line"></span><br><span class="line">反射是在运行状态中，对于任意一个类，都能够知道这个类的所有属性和方法；对于任意一个对象，都能够调用它的任意一个方法和属性；这种动态获取的信息以及动态调用对象的方法的功能称为 Java 语言的反射机制。</span><br><span class="line"></span><br><span class="line">58. 什么是 Java 序列化？什么情况下需要序列化？</span><br><span class="line"></span><br><span class="line">Java 序列化是为了保存各种对象在内存中的状态，并且可以把保存的对象状态再读出来。</span><br><span class="line"></span><br><span class="line">以下情况需要使用 Java 序列化：</span><br><span class="line"></span><br><span class="line">想把的内存中的对象状态保存到一个文件中或者数据库中时候；</span><br><span class="line">想用套接字在网络上传送对象的时候；</span><br><span class="line">想通过RMI（远程方法调用）传输对象的时候。</span><br><span class="line">59. 动态代理是什么？有哪些应用？</span><br><span class="line"></span><br><span class="line">动态代理是运行时动态生成代理类。</span><br><span class="line"></span><br><span class="line">动态代理的应用有 spring aop、hibernate 数据查询、测试框架的后端 mock、rpc，Java注解对象获取等。</span><br><span class="line"></span><br><span class="line">60. 怎么实现动态代理？</span><br><span class="line"></span><br><span class="line">JDK 原生动态代理和 cglib 动态代理。JDK 原生动态代理是基于接口实现的，而 cglib 是基于继承当前类的子类实现的。</span><br><span class="line"></span><br><span class="line">对象拷贝</span><br><span class="line"></span><br><span class="line">61. 为什么要使用克隆？</span><br><span class="line"></span><br><span class="line">克隆的对象可能包含一些已经修改过的属性，而 new 出来的对象的属性都还是初始化时候的值，所以当需要一个新的对象来保存当前对象的“状态”就靠克隆方法了。</span><br><span class="line"></span><br><span class="line">62. 如何实现对象克隆？</span><br><span class="line"></span><br><span class="line">实现 Cloneable 接口并重写 Object 类中的 clone() 方法。</span><br><span class="line">实现 Serializable 接口，通过对象的序列化和反序列化实现克隆，可以实现真正的深度克隆。</span><br><span class="line">63. 深拷贝和浅拷贝区别是什么？</span><br><span class="line"></span><br><span class="line">浅克隆：当对象被复制时只复制它本身和其中包含的值类型的成员变量，而引用类型的成员对象并没有复制。</span><br><span class="line">深克隆：除了对象本身被复制外，对象所包含的所有成员变量也将复制。</span><br><span class="line">Java Web</span><br><span class="line"></span><br><span class="line">64. JSP 和 servlet 有什么区别？</span><br><span class="line"></span><br><span class="line">JSP 是 servlet 技术的扩展，本质上就是 servlet 的简易方式。servlet 和 JSP 最主要的不同点在于，servlet 的应用逻辑是在 Java 文件中，并且完全从表示层中的 html 里分离开来，而 JSP 的情况是 Java 和 html 可以组合成一个扩展名为 JSP 的文件。JSP 侧重于视图，servlet 主要用于控制逻辑。</span><br><span class="line"></span><br><span class="line">65. JSP 有哪些内置对象？作用分别是什么？</span><br><span class="line"></span><br><span class="line">JSP 有 9 大内置对象：</span><br><span class="line"></span><br><span class="line">request：封装客户端的请求，其中包含来自 get 或 post 请求的参数；</span><br><span class="line">response：封装服务器对客户端的响应；</span><br><span class="line">pageContext：通过该对象可以获取其他对象；</span><br><span class="line">session：封装用户会话的对象；</span><br><span class="line">application：封装服务器运行环境的对象；</span><br><span class="line">out：输出服务器响应的输出流对象；</span><br><span class="line">config：Web 应用的配置对象；</span><br><span class="line">page：JSP 页面本身（相当于 Java 程序中的 this）；</span><br><span class="line">exception：封装页面抛出异常的对象。</span><br><span class="line">66. 说一下 JSP 的 4 种作用域？</span><br><span class="line"></span><br><span class="line">page：代表与一个页面相关的对象和属性。</span><br><span class="line">request：代表与客户端发出的一个请求相关的对象和属性。一个请求可能跨越多个页面，涉及多个 Web 组件；需要在页面显示的临时数据可以置于此作用域。</span><br><span class="line">session：代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的 session 中。</span><br><span class="line">application：代表与整个 Web 应用程序相关的对象和属性，它实质上是跨越整个 Web 应用程序，包括多个页面、请求和会话的一个全局作用域。</span><br><span class="line">67. session 和 cookie 有什么区别？</span><br><span class="line"></span><br><span class="line">存储位置不同：session 存储在服务器端；cookie 存储在浏览器端。</span><br><span class="line">安全性不同：cookie 安全性一般，在浏览器存储，可以被伪造和修改。</span><br><span class="line">容量和个数限制：cookie 有容量限制，每个站点下的 cookie 也有个数限制。</span><br><span class="line">存储的多样性：session 可以存储在 Redis 中、数据库中、应用程序中；而 cookie 只能存储在浏览器中。</span><br><span class="line">68. 说一下 session 的工作原理？</span><br><span class="line"></span><br><span class="line">session 的工作原理是客户端登录完成之后，服务器会创建对应的 session，session 创建完之后，会把 session 的 id 发送给客户端，客户端再存储到浏览器中。这样客户端每次访问服务器时，都会带着 sessionid，服务器拿到 sessionid 之后，在内存找到与之对应的 session 这样就可以正常工作了。</span><br><span class="line"></span><br><span class="line">69. 如果客户端禁止 cookie 能实现 session 还能用吗？</span><br><span class="line"></span><br><span class="line">可以用，session 只是依赖 cookie 存储 sessionid，如果 cookie 被禁用了，可以使用 url 中添加 sessionid 的方式保证 session 能正常使用。</span><br><span class="line"></span><br><span class="line">70. spring mvc 和 struts 的区别是什么？</span><br><span class="line"></span><br><span class="line">拦截级别：struts2 是类级别的拦截；spring mvc 是方法级别的拦截。</span><br><span class="line">数据独立性：spring mvc 的方法之间基本上独立的，独享 request 和 response 数据，请求数据通过参数获取，处理结果通过 ModelMap 交回给框架，方法之间不共享变量；而 struts2 虽然方法之间也是独立的，但其所有 action 变量是共享的，这不会影响程序运行，却给我们编码和读程序时带来了一定的麻烦。</span><br><span class="line">拦截机制：struts2 有以自己的 interceptor 机制，spring mvc 用的是独立的 aop 方式，这样导致struts2 的配置文件量比 spring mvc 大。</span><br><span class="line">对 ajax 的支持：spring mvc 集成了ajax，所有 ajax 使用很方便，只需要一个注解 @ResponseBody 就可以实现了；而 struts2 一般需要安装插件或者自己写代码才行。</span><br><span class="line">71. 如何避免 SQL 注入？</span><br><span class="line"></span><br><span class="line">使用预处理 PreparedStatement。</span><br><span class="line">使用正则表达式过滤掉字符中的特殊字符。</span><br><span class="line">72. 什么是 XSS 攻击，如何避免？</span><br><span class="line"></span><br><span class="line">XSS 攻击：即跨站脚本攻击，它是 Web 程序中常见的漏洞。原理是攻击者往 Web 页面里插入恶意的脚本代码（css 代码、Javascript 代码等），当用户浏览该页面时，嵌入其中的脚本代码会被执行，从而达到恶意攻击用户的目的，如盗取用户 cookie、破坏页面结构、重定向到其他网站等。</span><br><span class="line"></span><br><span class="line">预防 XSS 的核心是必须对输入的数据做过滤处理。</span><br><span class="line"></span><br><span class="line">73. 什么是 CSRF 攻击，如何避免？</span><br><span class="line"></span><br><span class="line">CSRF：Cross-Site Request Forgery（中文：跨站请求伪造），可以理解为攻击者盗用了你的身份，以你的名义发送恶意请求，比如：以你名义发送邮件、发消息、购买商品，虚拟货币转账等。</span><br><span class="line"></span><br><span class="line">防御手段：</span><br><span class="line"></span><br><span class="line">验证请求来源地址；</span><br><span class="line">关键操作添加验证码；</span><br><span class="line">在请求地址添加 token 并验证。</span><br><span class="line">异常</span><br><span class="line"></span><br><span class="line">74. throw 和 throws 的区别？</span><br><span class="line"></span><br><span class="line">throw：是真实抛出一个异常。</span><br><span class="line">throws：是声明可能会抛出一个异常。</span><br><span class="line">75. final、finally、finalize 有什么区别？</span><br><span class="line"></span><br><span class="line">final：是修饰符，如果修饰类，此类不能被继承；如果修饰方法和变量，则表示此方法和此变量不能在被改变，只能使用。</span><br><span class="line">finally：是 try&#123;&#125; catch&#123;&#125; finally&#123;&#125; 最后一部分，表示不论发生任何情况都会执行，finally 部分可以省略，但如果 finally 部分存在，则一定会执行 finally 里面的代码。</span><br><span class="line">finalize： 是 Object 类的一个方法，在垃圾收集器执行的时候会调用被回收对象的此方法。</span><br><span class="line">76. try-catch-finally 中哪个部分可以省略？</span><br><span class="line"></span><br><span class="line">try-catch-finally 其中 catch 和 finally 都可以被省略，但是不能同时省略，也就是说有 try 的时候，必须后面跟一个 catch 或者 finally。</span><br><span class="line"></span><br><span class="line">77. try-catch-finally 中，如果 catch 中 return 了，finally 还会执行吗？</span><br><span class="line"></span><br><span class="line">finally 一定会执行，即使是 catch 中 return 了，catch 中的 return 会等 finally 中的代码执行完之后，才会执行。</span><br><span class="line"></span><br><span class="line">78. 常见的异常类有哪些？</span><br><span class="line"></span><br><span class="line">NullPointerException 空指针异常</span><br><span class="line">ClassNotFoundException 指定类不存在</span><br><span class="line">NumberFormatException 字符串转换为数字异常</span><br><span class="line">IndexOutOfBoundsException 数组下标越界异常</span><br><span class="line">ClassCastException 数据类型转换异常</span><br><span class="line">FileNotFoundException 文件未找到异常</span><br><span class="line">NoSuchMethodException 方法不存在异常</span><br><span class="line">IOException IO 异常</span><br><span class="line">SocketException Socket 异常</span><br><span class="line">网络</span><br><span class="line"></span><br><span class="line">79. http 响应码 301 和 302 代表的是什么？有什么区别？</span><br><span class="line"></span><br><span class="line">301：永久重定向。</span><br><span class="line"></span><br><span class="line">302：暂时重定向。</span><br><span class="line"></span><br><span class="line">它们的区别是，301 对搜索引擎优化（SEO）更加有利；302 有被提示为网络拦截的风险。</span><br><span class="line"></span><br><span class="line">80. forward 和 redirect 的区别？</span><br><span class="line"></span><br><span class="line">forward 是转发 和 redirect 是重定向：</span><br><span class="line"></span><br><span class="line">地址栏 url 显示：foward url 不会发生改变，redirect url 会发生改变；</span><br><span class="line">数据共享：forward 可以共享 request 里的数据，redirect 不能共享；</span><br><span class="line">效率：forward 比 redirect 效率高。</span><br><span class="line">81. 简述 tcp 和 udp的区别？</span><br><span class="line"></span><br><span class="line">tcp 和 udp 是 OSI 模型中的运输层中的协议。tcp 提供可靠的通信传输，而 udp 则常被用于让广播和细节控制交给应用的通信传输。</span><br><span class="line"></span><br><span class="line">两者的区别大致如下：</span><br><span class="line"></span><br><span class="line">tcp 面向连接，udp 面向非连接即发送数据前不需要建立链接；</span><br><span class="line">tcp 提供可靠的服务（数据传输），udp 无法保证；</span><br><span class="line">tcp 面向字节流，udp 面向报文；</span><br><span class="line">tcp 数据传输慢，udp 数据传输快；</span><br><span class="line">82. tcp 为什么要三次握手，两次不行吗？为什么？</span><br><span class="line"></span><br><span class="line">如果采用两次握手，那么只要服务器发出确认数据包就会建立连接，但由于客户端此时并未响应服务器端的请求，那此时服务器端就会一直在等待客户端，这样服务器端就白白浪费了一定的资源。若采用三次握手，服务器端没有收到来自客户端的再此确认，则就会知道客户端并没有要求建立请求，就不会浪费服务器的资源。</span><br><span class="line"></span><br><span class="line">83. 说一下 tcp 粘包是怎么产生的？</span><br><span class="line"></span><br><span class="line">tcp 粘包可能发生在发送端或者接收端，分别来看两端各种产生粘包的原因：</span><br><span class="line"></span><br><span class="line">发送端粘包：发送端需要等缓冲区满才发送出去，造成粘包；</span><br><span class="line">接收方粘包：接收方不及时接收缓冲区的包，造成多个包接收。</span><br><span class="line">84. OSI 的七层模型都有哪些？</span><br><span class="line"></span><br><span class="line">物理层：利用传输介质为数据链路层提供物理连接，实现比特流的透明传输。</span><br><span class="line">数据链路层：负责建立和管理节点间的链路。</span><br><span class="line">网络层：通过路由选择算法，为报文或分组通过通信子网选择最适当的路径。</span><br><span class="line">传输层：向用户提供可靠的端到端的差错和流量控制，保证报文的正确传输。</span><br><span class="line">会话层：向两个实体的表示层提供建立和使用连接的方法。</span><br><span class="line">表示层：处理用户信息的表示问题，如编码、数据格式转换和加密解密等。</span><br><span class="line">应用层：直接向用户提供服务，完成用户希望在网络上完成的各种工作。</span><br><span class="line">85. get 和 post 请求有哪些区别？</span><br><span class="line"></span><br><span class="line">get 请求会被浏览器主动缓存，而 post 不会。</span><br><span class="line">get 传递参数有大小限制，而 post 没有。</span><br><span class="line">post 参数传输更安全，get 的参数会明文限制在 url 上，post 不会。</span><br><span class="line">86. 如何实现跨域？</span><br><span class="line"></span><br><span class="line">实现跨域有以下几种方案：</span><br><span class="line"></span><br><span class="line">服务器端运行跨域 设置 CORS 等于 *；</span><br><span class="line">在单个接口使用注解 @CrossOrigin 运行跨域；</span><br><span class="line">使用 jsonp 跨域；</span><br><span class="line">87. 说一下 JSONP 实现原理？</span><br><span class="line"></span><br><span class="line">jsonp：JSON with Padding，它是利用script标签的 src 连接可以访问不同源的特性，加载远程返回的“JS 函数”来执行的。</span><br><span class="line"></span><br><span class="line">设计模式</span><br><span class="line"></span><br><span class="line">88. 说一下你熟悉的设计模式？</span><br><span class="line"></span><br><span class="line">单例模式：保证被创建一次，节省系统开销。</span><br><span class="line">工厂模式（简单工厂、抽象工厂）：解耦代码。</span><br><span class="line">观察者模式：定义了对象之间的一对多的依赖，这样一来，当一个对象改变时，它的所有的依赖者都会收到通知并自动更新。</span><br><span class="line">外观模式：提供一个统一的接口，用来访问子系统中的一群接口，外观定义了一个高层的接口，让子系统更容易使用。</span><br><span class="line">模版方法模式：定义了一个算法的骨架，而将一些步骤延迟到子类中，模版方法使得子类可以在不改变算法结构的情况下，重新定义算法的步骤。</span><br><span class="line">状态模式：允许对象在内部状态改变时改变它的行为，对象看起来好像修改了它的类。</span><br><span class="line">89. 简单工厂和抽象工厂有什么区别？</span><br><span class="line"></span><br><span class="line">简单工厂：用来生产同一等级结构中的任意产品，对于增加新的产品，无能为力。</span><br><span class="line">工厂方法：用来生产同一等级结构中的固定产品，支持增加任意产品。</span><br><span class="line">抽象工厂：用来生产不同产品族的全部产品，对于增加新的产品，无能为力；支持增加产品族。</span><br><span class="line">Spring/Spring MVC</span><br><span class="line"></span><br><span class="line">90. 为什么要使用 spring？</span><br><span class="line"></span><br><span class="line">spring 提供 ioc 技术，容器会帮你管理依赖的对象，从而不需要自己创建和管理依赖对象了，更轻松的实现了程序的解耦。</span><br><span class="line">spring 提供了事务支持，使得事务操作变的更加方便。</span><br><span class="line">spring 提供了面向切片编程，这样可以更方便的处理某一类的问题。</span><br><span class="line">更方便的框架集成，spring 可以很方便的集成其他框架，比如 MyBatis、hibernate 等。</span><br><span class="line">91. 解释一下什么是 aop？</span><br><span class="line"></span><br><span class="line">aop 是面向切面编程，通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。</span><br><span class="line"></span><br><span class="line">简单来说就是统一处理某一“切面”（类）的问题的编程思想，比如统一处理日志、异常等。</span><br><span class="line"></span><br><span class="line">92. 解释一下什么是 ioc？</span><br><span class="line"></span><br><span class="line">ioc：Inversionof Control（中文：控制反转）是 spring 的核心，对于 spring 框架来说，就是由 spring 来负责控制对象的生命周期和对象间的关系。</span><br><span class="line"></span><br><span class="line">简单来说，控制指的是当前对象对内部成员的控制权；控制反转指的是，这种控制权不由当前对象管理了，由其他（类,第三方容器）来管理。</span><br><span class="line"></span><br><span class="line">93. spring 有哪些主要模块？</span><br><span class="line"></span><br><span class="line">spring core：框架的最基础部分，提供 ioc 和依赖注入特性。</span><br><span class="line">spring context：构建于 core 封装包基础上的 context 封装包，提供了一种框架式的对象访问方法。</span><br><span class="line">spring dao：Data Access Object 提供了JDBC的抽象层。</span><br><span class="line">spring aop：提供了面向切面的编程实现，让你可以自定义拦截器、切点等。</span><br><span class="line">spring Web：提供了针对 Web 开发的集成特性，例如文件上传，利用 servlet listeners 进行 ioc 容器初始化和针对 Web 的 ApplicationContext。</span><br><span class="line">spring Web mvc：spring 中的 mvc 封装包提供了 Web 应用的 Model-View-Controller（MVC）的实现。</span><br><span class="line">94. spring 常用的注入方式有哪些？</span><br><span class="line"></span><br><span class="line">setter 属性注入</span><br><span class="line">构造方法注入</span><br><span class="line">注解方式注入</span><br><span class="line">95. spring 中的 bean 是线程安全的吗？</span><br><span class="line"></span><br><span class="line">spring 中的 bean 默认是单例模式，spring 框架并没有对单例 bean 进行多线程的封装处理。</span><br><span class="line"></span><br><span class="line">实际上大部分时候 spring bean 无状态的（比如 dao 类），所有某种程度上来说 bean 也是安全的，但如果 bean 有状态的话（比如 view model 对象），那就要开发者自己去保证线程安全了，最简单的就是改变 bean 的作用域，把“singleton”变更为“prototype”，这样请求 bean 相当于 new Bean()了，所以就可以保证线程安全了。</span><br><span class="line"></span><br><span class="line">有状态就是有数据存储功能。</span><br><span class="line">无状态就是不会保存数据。</span><br><span class="line">96. spring 支持几种 bean 的作用域？</span><br><span class="line"></span><br><span class="line">spring 支持 5 种作用域，如下：</span><br><span class="line"></span><br><span class="line">singleton：spring ioc 容器中只存在一个 bean 实例，bean 以单例模式存在，是系统默认值；</span><br><span class="line">prototype：每次从容器调用 bean 时都会创建一个新的示例，既每次 getBean()相当于执行 new Bean()操作；</span><br><span class="line">Web 环境下的作用域：</span><br><span class="line">request：每次 http 请求都会创建一个 bean；</span><br><span class="line">session：同一个 http session 共享一个 bean 实例；</span><br><span class="line">global-session：用于 portlet 容器，因为每个 portlet 有单独的 session，globalsession 提供一个全局性的 http session。</span><br><span class="line">注意： 使用 prototype 作用域需要慎重的思考，因为频繁创建和销毁 bean 会带来很大的性能开销。</span><br><span class="line"></span><br><span class="line">97. spring 自动装配 bean 有哪些方式？</span><br><span class="line"></span><br><span class="line">no：默认值，表示没有自动装配，应使用显式 bean 引用进行装配。</span><br><span class="line">byName：它根据 bean 的名称注入对象依赖项。</span><br><span class="line">byType：它根据类型注入对象依赖项。</span><br><span class="line">构造函数：通过构造函数来注入依赖项，需要设置大量的参数。</span><br><span class="line">autodetect：容器首先通过构造函数使用 autowire 装配，如果不能，则通过 byType 自动装配。</span><br><span class="line">98. spring 事务实现方式有哪些？</span><br><span class="line"></span><br><span class="line">声明式事务：声明式事务也有两种实现方式，基于 xml 配置文件的方式和注解方式（在类上添加 @Transaction 注解）。</span><br><span class="line">编码方式：提供编码的形式管理和维护事务。</span><br><span class="line">99. 说一下 spring 的事务隔离？</span><br><span class="line"></span><br><span class="line">spring 有五大隔离级别，默认值为 ISOLATION_DEFAULT（使用数据库的设置），其他四个隔离级别和数据库的隔离级别一致：</span><br><span class="line"></span><br><span class="line">ISOLATION_DEFAULT：用底层数据库的设置隔离级别，数据库设置的是什么我就用什么；</span><br><span class="line"></span><br><span class="line">ISOLATIONREADUNCOMMITTED：未提交读，最低隔离级别、事务未提交前，就可被其他事务读取（会出现幻读、脏读、不可重复读）；</span><br><span class="line"></span><br><span class="line">ISOLATIONREADCOMMITTED：提交读，一个事务提交后才能被其他事务读取到（会造成幻读、不可重复读），SQL server 的默认级别；</span><br><span class="line"></span><br><span class="line">ISOLATIONREPEATABLEREAD：可重复读，保证多次读取同一个数据时，其值都和事务开始时候的内容是一致，禁止读取到别的事务未提交的数据（会造成幻读），MySQL 的默认级别；</span><br><span class="line"></span><br><span class="line">ISOLATION_SERIALIZABLE：序列化，代价最高最可靠的隔离级别，该隔离级别能防止脏读、不可重复读、幻读。</span><br><span class="line"></span><br><span class="line">脏读 ：表示一个事务能够读取另一个事务中还未提交的数据。比如，某个事务尝试插入记录 A，此时该事务还未提交，然后另一个事务尝试读取到了记录 A。</span><br><span class="line"></span><br><span class="line">不可重复读 ：是指在一个事务内，多次读同一数据。</span><br><span class="line"></span><br><span class="line">幻读 ：指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录，但是第二次同等条件下查询却有 n+1 条记录，这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据，同一个记录的数据内容被修改了，所有数据行的记录就变多或者变少了。</span><br><span class="line"></span><br><span class="line">100. 说一下 spring mvc 运行流程？</span><br><span class="line"></span><br><span class="line">spring mvc 先将请求发送给 DispatcherServlet。</span><br><span class="line">DispatcherServlet 查询一个或多个 HandlerMapping，找到处理请求的 Controller。</span><br><span class="line">DispatcherServlet 再把请求提交到对应的 Controller。</span><br><span class="line">Controller 进行业务逻辑处理后，会返回一个ModelAndView。</span><br><span class="line">Dispathcher 查询一个或多个 ViewResolver 视图解析器，找到 ModelAndView 对象指定的视图对象。</span><br><span class="line">视图对象负责渲染返回给客户端。</span><br><span class="line">101. spring mvc 有哪些组件？</span><br><span class="line"></span><br><span class="line">前置控制器 DispatcherServlet。</span><br><span class="line">映射控制器 HandlerMapping。</span><br><span class="line">处理器 Controller。</span><br><span class="line">模型和视图 ModelAndView。</span><br><span class="line">视图解析器 ViewResolver。</span><br><span class="line">102. @RequestMapping 的作用是什么？</span><br><span class="line"></span><br><span class="line">将 http 请求映射到相应的类/方法上。</span><br><span class="line"></span><br><span class="line">103. @Autowired 的作用是什么？</span><br><span class="line"></span><br><span class="line">@Autowired 它可以对类成员变量、方法及构造函数进行标注，完成自动装配的工作，通过@Autowired 的使用来消除 set/get 方法。</span><br><span class="line"></span><br><span class="line">Spring Boot/Spring Cloud</span><br><span class="line"></span><br><span class="line">104. 什么是 spring boot？</span><br><span class="line"></span><br><span class="line">spring boot 是为 spring 服务的，是用来简化新 spring 应用的初始搭建以及开发过程的。</span><br><span class="line"></span><br><span class="line">105. 为什么要用 spring boot？</span><br><span class="line"></span><br><span class="line">配置简单</span><br><span class="line">独立运行</span><br><span class="line">自动装配</span><br><span class="line">无代码生成和 xml 配置</span><br><span class="line">提供应用监控</span><br><span class="line">易上手</span><br><span class="line">提升开发效率</span><br><span class="line">106. spring boot 核心配置文件是什么？</span><br><span class="line"></span><br><span class="line">spring boot 核心的两个配置文件：</span><br><span class="line"></span><br><span class="line">bootstrap (. yml 或者 . properties)：boostrap 由父 ApplicationContext 加载的，比 applicaton 优先加载，且 boostrap 里面的属性不能被覆盖；</span><br><span class="line">application (. yml 或者 . properties)：用于 spring boot 项目的自动化配置。</span><br><span class="line">107. spring boot 配置文件有哪几种类型？它们有什么区别？</span><br><span class="line"></span><br><span class="line">配置文件有 . properties 格式和 . yml 格式，它们主要的区别是书法风格不同。</span><br><span class="line"></span><br><span class="line">. properties 配置如下：</span><br><span class="line"></span><br><span class="line">spring. RabbitMQ. port=5672</span><br><span class="line">. yml 配置如下：</span><br><span class="line"></span><br><span class="line">spring:</span><br><span class="line">    RabbitMQ:</span><br><span class="line">        port: 5672</span><br><span class="line">. yml 格式不支持 @PropertySource 注解导入。</span><br><span class="line"></span><br><span class="line">108. spring boot 有哪些方式可以实现热部署？</span><br><span class="line"></span><br><span class="line">使用 devtools 启动热部署，添加 devtools 库，在配置文件中把 spring. devtools. restart. enabled 设置为 true；</span><br><span class="line">使用 Intellij Idea 编辑器，勾上自动编译或手动重新编译。</span><br><span class="line">109. jpa 和 hibernate 有什么区别？</span><br><span class="line"></span><br><span class="line">jpa 全称 Java Persistence API，是 Java 持久化接口规范，hibernate 属于 jpa 的具体实现。</span><br><span class="line"></span><br><span class="line">110. 什么是 spring cloud？</span><br><span class="line"></span><br><span class="line">spring cloud 是一系列框架的有序集合。它利用 spring boot 的开发便利性巧妙地简化了分布式系统基础设施的开发，如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等，都可以用 spring boot 的开发风格做到一键启动和部署。</span><br><span class="line"></span><br><span class="line">111. spring cloud 断路器的作用是什么？</span><br><span class="line"></span><br><span class="line">在分布式架构中，断路器模式的作用也是类似的，当某个服务单元发生故障（类似用电器发生短路）之后，通过断路器的故障监控（类似熔断保险丝），向调用方返回一个错误响应，而不是长时间的等待。这样就不会使得线程因调用故障服务被长时间占用不释放，避免了故障在分布式系统中的蔓延。</span><br><span class="line"></span><br><span class="line">112. spring cloud 的核心组件有哪些？</span><br><span class="line"></span><br><span class="line">Eureka：服务注册于发现。</span><br><span class="line">Feign：基于动态代理机制，根据注解和选择的机器，拼接请求 url 地址，发起请求。</span><br><span class="line">Ribbon：实现负载均衡，从一个服务的多台机器中选择一台。</span><br><span class="line">Hystrix：提供线程池，不同的服务走不同的线程池，实现了不同服务调用的隔离，避免了服务雪崩的问题。</span><br><span class="line">Zuul：网关管理，由 Zuul 网关转发请求给对应的服务。</span><br><span class="line">Hibernate</span><br><span class="line"></span><br><span class="line">113. 为什么要使用 hibernate？</span><br><span class="line"></span><br><span class="line">hibernate 是对 jdbc 的封装，大大简化了数据访问层的繁琐的重复性代码。</span><br><span class="line">hibernate 是一个优秀的 ORM 实现，很多程度上简化了 DAO 层的编码功能。</span><br><span class="line">可以很方便的进行数据库的移植工作。</span><br><span class="line">提供了缓存机制，是程序执行更改的高效。</span><br><span class="line">114. 什么是 ORM 框架？</span><br><span class="line"></span><br><span class="line">ORM（Object Relation Mapping）对象关系映射，是把数据库中的关系数据映射成为程序中的对象。</span><br><span class="line"></span><br><span class="line">使用 ORM 的优点：提高了开发效率降低了开发成本、开发更简单更对象化、可移植更强。</span><br><span class="line"></span><br><span class="line">115. hibernate 中如何在控制台查看打印的 SQL 语句？</span><br><span class="line"></span><br><span class="line">在 Config 里面把 hibernate. show_SQL 设置为 true 就可以。但不建议开启，开启之后会降低程序的运行效率。</span><br><span class="line"></span><br><span class="line">116. hibernate 有几种查询方式？</span><br><span class="line"></span><br><span class="line">三种：hql、原生 SQL、条件查询 Criteria。</span><br><span class="line"></span><br><span class="line">117. hibernate 实体类可以被定义为 final 吗？</span><br><span class="line"></span><br><span class="line">实体类可以定义为 final 类，但这样的话就不能使用 hibernate 代理模式下的延迟关联提供性能了，所以不建议定义实体类为 final。</span><br><span class="line"></span><br><span class="line">118. 在 hibernate 中使用 Integer 和 int 做映射有什么区别？</span><br><span class="line"></span><br><span class="line">Integer 类型为对象，它的值允许为 null，而 int 属于基础数据类型，值不能为 null。</span><br><span class="line"></span><br><span class="line">119. hibernate 是如何工作的？</span><br><span class="line"></span><br><span class="line">读取并解析配置文件。</span><br><span class="line">读取并解析映射文件，创建 SessionFactory。</span><br><span class="line">打开 Session。</span><br><span class="line">创建事务。</span><br><span class="line">进行持久化操作。</span><br><span class="line">提交事务。</span><br><span class="line">关闭 Session。</span><br><span class="line">关闭 SessionFactory。</span><br><span class="line">120. get()和 load()的区别？</span><br><span class="line"></span><br><span class="line">数据查询时，没有 OID 指定的对象，get() 返回 null；load() 返回一个代理对象。</span><br><span class="line">load()支持延迟加载；get() 不支持延迟加载。</span><br><span class="line">121. 说一下 hibernate 的缓存机制？</span><br><span class="line"></span><br><span class="line">hibernate 常用的缓存有一级缓存和二级缓存：</span><br><span class="line"></span><br><span class="line">一级缓存：也叫 Session 缓存，只在 Session 作用范围内有效，不需要用户干涉，由 hibernate 自身维护，可以通过：evict(object)清除 object 的缓存；clear()清除一级缓存中的所有缓存；flush()刷出缓存；</span><br><span class="line"></span><br><span class="line">二级缓存：应用级别的缓存，在所有 Session 中都有效，支持配置第三方的缓存，如：EhCache。</span><br><span class="line"></span><br><span class="line">122. hibernate 对象有哪些状态？</span><br><span class="line"></span><br><span class="line">临时/瞬时状态：直接 new 出来的对象，该对象还没被持久化（没保存在数据库中），不受 Session 管理。</span><br><span class="line">持久化状态：当调用 Session 的 save/saveOrupdate/get/load/list 等方法的时候，对象就是持久化状态。</span><br><span class="line">游离状态：Session 关闭之后对象就是游离状态。</span><br><span class="line">123. 在 hibernate 中 getCurrentSession 和 openSession 的区别是什么？</span><br><span class="line"></span><br><span class="line">getCurrentSession 会绑定当前线程，而 openSession 则不会。</span><br><span class="line">getCurrentSession 事务是 Spring 控制的，并且不需要手动关闭，而 openSession 需要我们自己手动开启和提交事务。</span><br><span class="line">124. hibernate 实体类必须要有无参构造函数吗？为什么？</span><br><span class="line"></span><br><span class="line">hibernate 中每个实体类必须提供一个无参构造函数，因为 hibernate 框架要使用 reflection api，通过调用 ClassnewInstance() 来创建实体类的实例，如果没有无参的构造函数就会抛出异常。</span><br><span class="line"></span><br><span class="line">MyBatis</span><br><span class="line"></span><br><span class="line">125. MyBatis 中 #&#123;&#125;和 $&#123;&#125;的区别是什么？</span><br><span class="line"></span><br><span class="line">\#&#123;&#125;是预编译处理，$&#123;&#125;是字符替换。 在使用 #&#123;&#125;时，MyBatis 会将 SQL 中的 #&#123;&#125;替换成“?”，配合 PreparedStatement 的 set 方法赋值，这样可以有效的防止 SQL 注入，保证程序的运行安全。</span><br><span class="line"></span><br><span class="line">126. MyBatis 有几种分页方式？</span><br><span class="line"></span><br><span class="line">分页方式：逻辑分页和物理分页。</span><br><span class="line"></span><br><span class="line">逻辑分页： 使用 MyBatis 自带的 RowBounds 进行分页，它是一次性查询很多数据，然后在数据中再进行检索。</span><br><span class="line"></span><br><span class="line">物理分页： 自己手写 SQL 分页或使用分页插件 PageHelper，去数据库查询指定条数的分页数据的形式。</span><br><span class="line"></span><br><span class="line">127. RowBounds 是一次性查询全部结果吗？为什么？</span><br><span class="line"></span><br><span class="line">RowBounds 表面是在“所有”数据中检索数据，其实并非是一次性查询出所有数据，因为 MyBatis 是对 jdbc 的封装，在 jdbc 驱动中有一个 Fetch Size 的配置，它规定了每次最多从数据库查询多少条数据，假如你要查询更多数据，它会在你执行 next()的时候，去查询更多的数据。就好比你去自动取款机取 10000 元，但取款机每次最多能取 2500 元，所以你要取 4 次才能把钱取完。只是对于 jdbc 来说，当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。</span><br><span class="line"></span><br><span class="line">Fetch Size 官方相关文档：http://t. cn/EfSE2g3</span><br><span class="line"></span><br><span class="line">128. MyBatis 逻辑分页和物理分页的区别是什么？</span><br><span class="line"></span><br><span class="line">逻辑分页是一次性查询很多数据，然后再在结果中检索分页的数据。这样做弊端是需要消耗大量的内存、有内存溢出的风险、对数据库压力较大。</span><br><span class="line">物理分页是从数据库查询指定条数的数据，弥补了一次性全部查出的所有数据的种种缺点，比如需要大量的内存，对数据库查询压力较大等问题。</span><br><span class="line">129. MyBatis 是否支持延迟加载？延迟加载的原理是什么？</span><br><span class="line"></span><br><span class="line">MyBatis 支持延迟加载，设置 lazyLoadingEnabled=true 即可。</span><br><span class="line"></span><br><span class="line">延迟加载的原理的是调用的时候触发加载，而不是在初始化的时候就加载信息。比如调用 a. getB(). getName()，这个时候发现 a. getB() 的值为 null，此时会单独触发事先保存好的关联 B 对象的 SQL，先查询出来 B，然后再调用 a. setB(b)，而这时候再调用 a. getB(). getName() 就有值了，这就是延迟加载的基本原理。</span><br><span class="line"></span><br><span class="line">130. 说一下 MyBatis 的一级缓存和二级缓存？</span><br><span class="line"></span><br><span class="line">一级缓存：基于 PerpetualCache 的 HashMap 本地缓存，它的声明周期是和 SQLSession 一致的，有多个 SQLSession 或者分布式的环境中数据库操作，可能会出现脏数据。当 Session flush 或 close 之后，该 Session 中的所有 Cache 就将清空，默认一级缓存是开启的。</span><br><span class="line">二级缓存：也是基于 PerpetualCache 的 HashMap 本地缓存，不同在于其存储作用域为 Mapper 级别的，如果多个SQLSession之间需要共享缓存，则需要使用到二级缓存，并且二级缓存可自定义存储源，如 Ehcache。默认不打开二级缓存，要开启二级缓存，使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态)。</span><br><span class="line">开启二级缓存数据查询流程：二级缓存 -&gt; 一级缓存 -&gt; 数据库。</span><br><span class="line"></span><br><span class="line">缓存更新机制：当某一个作用域(一级缓存 Session/二级缓存 Mapper)进行了C/U/D 操作后，默认该作用域下所有 select 中的缓存将被 clear。</span><br><span class="line"></span><br><span class="line">131. MyBatis 和 hibernate 的区别有哪些？</span><br><span class="line"></span><br><span class="line">灵活性：MyBatis 更加灵活，自己可以写 SQL 语句，使用起来比较方便。</span><br><span class="line">可移植性：MyBatis 有很多自己写的 SQL，因为每个数据库的 SQL 可以不相同，所以可移植性比较差。</span><br><span class="line">学习和使用门槛：MyBatis 入门比较简单，使用门槛也更低。</span><br><span class="line">二级缓存：hibernate 拥有更好的二级缓存，它的二级缓存可以自行更换为第三方的二级缓存。</span><br><span class="line">132. MyBatis 有哪些执行器（Executor）？</span><br><span class="line"></span><br><span class="line">MyBatis 有三种基本的Executor执行器：</span><br><span class="line"></span><br><span class="line">SimpleExecutor：每执行一次 update 或 select 就开启一个 Statement 对象，用完立刻关闭 Statement 对象；</span><br><span class="line">ReuseExecutor：执行 update 或 select，以 SQL 作为 key 查找 Statement 对象，存在就使用，不存在就创建，用完后不关闭 Statement 对象，而是放置于 Map 内供下一次使用。简言之，就是重复使用 Statement 对象；</span><br><span class="line">BatchExecutor：执行 update（没有 select，jdbc 批处理不支持 select），将所有 SQL 都添加到批处理中（addBatch()），等待统一执行（executeBatch()），它缓存了多个 Statement 对象，每个 Statement 对象都是 addBatch()完毕后，等待逐一执行 executeBatch()批处理，与 jdbc 批处理相同。</span><br><span class="line">133. MyBatis 分页插件的实现原理是什么？</span><br><span class="line"></span><br><span class="line">分页插件的基本原理是使用 MyBatis 提供的插件接口，实现自定义插件，在插件的拦截方法内拦截待执行的 SQL，然后重写 SQL，根据 dialect 方言，添加对应的物理分页语句和物理分页参数。</span><br><span class="line"></span><br><span class="line">134. MyBatis 如何编写一个自定义插件？</span><br><span class="line"></span><br><span class="line">自定义插件实现原理</span><br><span class="line"></span><br><span class="line">MyBatis 自定义插件针对 MyBatis 四大对象（Executor、StatementHandler、ParameterHandler、ResultSetHandler）进行拦截：</span><br><span class="line"></span><br><span class="line">Executor：拦截内部执行器，它负责调用 StatementHandler 操作数据库，并把结果集通过 ResultSetHandler 进行自动映射，另外它还处理了二级缓存的操作；</span><br><span class="line">StatementHandler：拦截 SQL 语法构建的处理，它是 MyBatis 直接和数据库执行 SQL 脚本的对象，另外它也实现了 MyBatis 的一级缓存；</span><br><span class="line">ParameterHandler：拦截参数的处理；</span><br><span class="line">ResultSetHandler：拦截结果集的处理。</span><br><span class="line">自定义插件实现关键</span><br><span class="line"></span><br><span class="line">MyBatis 插件要实现 Interceptor 接口，接口包含的方法，如下：</span><br><span class="line"></span><br><span class="line">public interface Interceptor &#123;   </span><br><span class="line">   Object intercept(Invocation invocation) throws Throwable;       </span><br><span class="line">   Object plugin(Object target);    </span><br><span class="line">   void setProperties(Properties properties);</span><br><span class="line">&#125;</span><br><span class="line">setProperties 方法是在 MyBatis 进行配置插件的时候可以配置自定义相关属性，即：接口实现对象的参数配置；</span><br><span class="line">plugin 方法是插件用于封装目标对象的，通过该方法我们可以返回目标对象本身，也可以返回一个它的代理，可以决定是否要进行拦截进而决定要返回一个什么样的目标对象，官方提供了示例：return Plugin. wrap(target, this)；</span><br><span class="line">intercept 方法就是要进行拦截的时候要执行的方法。</span><br><span class="line">自定义插件实现示例</span><br><span class="line"></span><br><span class="line">官方插件实现：</span><br><span class="line"></span><br><span class="line">@Intercepts(&#123;@Signature(type = Executor. class, method = &quot;query&quot;,</span><br><span class="line">        args = &#123;MappedStatement. class, Object. class, RowBounds. class, ResultHandler. class&#125;)&#125;)</span><br><span class="line">public class TestInterceptor implements Interceptor &#123;</span><br><span class="line">   public Object intercept(Invocation invocation) throws Throwable &#123;</span><br><span class="line">     Object target = invocation. getTarget(); //被代理对象</span><br><span class="line">     Method method = invocation. getMethod(); //代理方法</span><br><span class="line">     Object[] args = invocation. getArgs(); //方法参数</span><br><span class="line">     // do something . . . . . .  方法拦截前执行代码块</span><br><span class="line">     Object result = invocation. proceed();</span><br><span class="line">     // do something . . . . . . . 方法拦截后执行代码块</span><br><span class="line">     return result;</span><br><span class="line">   &#125;</span><br><span class="line">   public Object plugin(Object target) &#123;</span><br><span class="line">     return Plugin. wrap(target, this);</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br><span class="line">RabbitMQ</span><br><span class="line"></span><br><span class="line">135. RabbitMQ 的使用场景有哪些？</span><br><span class="line"></span><br><span class="line">抢购活动，削峰填谷，防止系统崩塌。</span><br><span class="line">延迟信息处理，比如 10 分钟之后给下单未付款的用户发送邮件提醒。</span><br><span class="line">解耦系统，对于新增的功能可以单独写模块扩展，比如用户确认评价之后，新增了给用户返积分的功能，这个时候不用在业务代码里添加新增积分的功能，只需要把新增积分的接口订阅确认评价的消息队列即可，后面再添加任何功能只需要订阅对应的消息队列即可。</span><br><span class="line">136. RabbitMQ 有哪些重要的角色？</span><br><span class="line"></span><br><span class="line">RabbitMQ 中重要的角色有：生产者、消费者和代理：</span><br><span class="line"></span><br><span class="line">生产者：消息的创建者，负责创建和推送数据到消息服务器；</span><br><span class="line">消费者：消息的接收方，用于处理数据和确认消息；</span><br><span class="line">代理：就是 RabbitMQ 本身，用于扮演“快递”的角色，本身不生产消息，只是扮演“快递”的角色。</span><br><span class="line">137. RabbitMQ 有哪些重要的组件？</span><br><span class="line"></span><br><span class="line">ConnectionFactory（连接管理器）：应用程序与Rabbit之间建立连接的管理器，程序代码中使用。</span><br><span class="line">Channel（信道）：消息推送使用的通道。</span><br><span class="line">Exchange（交换器）：用于接受、分配消息。</span><br><span class="line">Queue（队列）：用于存储生产者的消息。</span><br><span class="line">RoutingKey（路由键）：用于把生成者的数据分配到交换器上。</span><br><span class="line">BindingKey（绑定键）：用于把交换器的消息绑定到队列上。</span><br><span class="line">138. RabbitMQ 中 vhost 的作用是什么？</span><br><span class="line"></span><br><span class="line">vhost：每个 RabbitMQ 都能创建很多 vhost，我们称之为虚拟主机，每个虚拟主机其实都是 mini 版的RabbitMQ，它拥有自己的队列，交换器和绑定，拥有自己的权限机制。</span><br><span class="line"></span><br><span class="line">139. RabbitMQ 的消息是怎么发送的？</span><br><span class="line"></span><br><span class="line">首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息，客户端和 rabbit server 之间会创建一个 tcp 连接，一旦 tcp 打开并通过了认证（认证就是你发送给 rabbit 服务器的用户名和密码），你的客户端和 RabbitMQ 就创建了一条 amqp 信道（channel），信道是创建在“真实” tcp 上的虚拟连接，amqp 命令都是通过信道发送出去的，每个信道都会有一个唯一的 id，不论是发布消息，订阅队列都是通过这个信道完成的。</span><br><span class="line"></span><br><span class="line">140. RabbitMQ 怎么保证消息的稳定性？</span><br><span class="line"></span><br><span class="line">提供了事务的功能。</span><br><span class="line">通过将 channel 设置为 confirm（确认）模式。</span><br><span class="line">141. RabbitMQ 怎么避免消息丢失？</span><br><span class="line"></span><br><span class="line">把消息持久化磁盘，保证服务器重启消息不丢失。</span><br><span class="line">每个集群中至少有一个物理磁盘，保证消息落入磁盘。</span><br><span class="line">142. 要保证消息持久化成功的条件有哪些？</span><br><span class="line"></span><br><span class="line">声明队列必须设置持久化 durable 设置为 true.</span><br><span class="line">消息推送投递模式必须设置持久化，deliveryMode 设置为 2（持久）。</span><br><span class="line">消息已经到达持久化交换器。</span><br><span class="line">消息已经到达持久化队列。</span><br><span class="line">以上四个条件都满足才能保证消息持久化成功。</span><br><span class="line"></span><br><span class="line">143. RabbitMQ 持久化有什么缺点？</span><br><span class="line"></span><br><span class="line">持久化的缺地就是降低了服务器的吞吐量，因为使用的是磁盘而非内存存储，从而降低了吞吐量。可尽量使用 ssd 硬盘来缓解吞吐量的问题。</span><br><span class="line"></span><br><span class="line">144. RabbitMQ 有几种广播类型？</span><br><span class="line"></span><br><span class="line">direct（默认方式）：最基础最简单的模式，发送方把消息发送给订阅方，如果有多个订阅者，默认采取轮询的方式进行消息发送。</span><br><span class="line">headers：与 direct 类似，只是性能很差，此类型几乎用不到。</span><br><span class="line">fanout：分发模式，把消费分发给所有订阅者。</span><br><span class="line">topic：匹配订阅模式，使用正则匹配到消息队列，能匹配到的都能接收到。</span><br><span class="line">145. RabbitMQ 怎么实现延迟消息队列？</span><br><span class="line"></span><br><span class="line">延迟队列的实现有两种方式：</span><br><span class="line"></span><br><span class="line">通过消息过期后进入死信交换器，再由交换器转发到延迟消费队列，实现延迟功能；</span><br><span class="line">使用 RabbitMQ-delayed-message-exchange 插件实现延迟功能。</span><br><span class="line">146. RabbitMQ 集群有什么用？</span><br><span class="line"></span><br><span class="line">集群主要有以下两个用途：</span><br><span class="line"></span><br><span class="line">高可用：某个服务器出现问题，整个 RabbitMQ 还可以继续使用；</span><br><span class="line">高容量：集群可以承载更多的消息量。</span><br><span class="line">147. RabbitMQ 节点的类型有哪些？</span><br><span class="line"></span><br><span class="line">磁盘节点：消息会存储到磁盘。</span><br><span class="line">内存节点：消息都存储在内存中，重启服务器消息丢失，性能高于磁盘类型。</span><br><span class="line">148. RabbitMQ 集群搭建需要注意哪些问题？</span><br><span class="line"></span><br><span class="line">各节点之间使用“--link”连接，此属性不能忽略。</span><br><span class="line">各节点使用的 erlang cookie 值必须相同，此值相当于“秘钥”的功能，用于各节点的认证。</span><br><span class="line">整个集群中必须包含一个磁盘节点。</span><br><span class="line">149. RabbitMQ 每个节点是其他节点的完整拷贝吗？为什么？</span><br><span class="line"></span><br><span class="line">不是，原因有以下两个：</span><br><span class="line"></span><br><span class="line">存储空间的考虑：如果每个节点都拥有所有队列的完全拷贝，这样新增节点不但没有新增存储空间，反而增加了更多的冗余数据；</span><br><span class="line">性能的考虑：如果每条消息都需要完整拷贝到每一个集群节点，那新增节点并没有提升处理消息的能力，最多是保持和单节点相同的性能甚至是更糟。</span><br><span class="line">150. RabbitMQ 集群中唯一一个磁盘节点崩溃了会发生什么情况？</span><br><span class="line"></span><br><span class="line">如果唯一磁盘的磁盘节点崩溃了，不能进行以下操作：</span><br><span class="line"></span><br><span class="line">不能创建队列</span><br><span class="line">不能创建交换器</span><br><span class="line">不能创建绑定</span><br><span class="line">不能添加用户</span><br><span class="line">不能更改权限</span><br><span class="line">不能添加和删除集群节点</span><br><span class="line">唯一磁盘节点崩溃了，集群是可以保持运行的，但你不能更改任何东西。</span><br><span class="line"></span><br><span class="line">151. RabbitMQ 对集群节点停止顺序有要求吗？</span><br><span class="line"></span><br><span class="line">RabbitMQ 对集群的停止的顺序是有要求的，应该先关闭内存节点，最后再关闭磁盘节点。如果顺序恰好相反的话，可能会造成消息的丢失。</span><br><span class="line"></span><br><span class="line">Kafka</span><br><span class="line"></span><br><span class="line">152. kafka 可以脱离 zookeeper 单独使用吗？为什么？</span><br><span class="line"></span><br><span class="line">kafka 不能脱离 zookeeper 单独使用，因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。</span><br><span class="line"></span><br><span class="line">153. kafka 有几种数据保留的策略？</span><br><span class="line"></span><br><span class="line">kafka 有两种数据保存策略：按照过期时间保留和按照存储的消息大小保留。</span><br><span class="line"></span><br><span class="line">154. kafka 同时设置了 7 天和 10G 清除数据，到第五天的时候消息达到了 10G，这个时候 kafka 将如何处理？</span><br><span class="line"></span><br><span class="line">这个时候 kafka 会执行数据清除工作，时间和大小不论那个满足条件，都会清空数据。</span><br><span class="line"></span><br><span class="line">155. 什么情况会导致 kafka 运行变慢？</span><br><span class="line"></span><br><span class="line">cpu 性能瓶颈</span><br><span class="line">磁盘读写瓶颈</span><br><span class="line">网络瓶颈</span><br><span class="line">156. 使用 kafka 集群需要注意什么？</span><br><span class="line"></span><br><span class="line">集群的数量不是越多越好，最好不要超过 7 个，因为节点越多，消息复制需要的时间就越长，整个群组的吞吐量就越低。</span><br><span class="line">集群数量最好是单数，因为超过一半故障集群就不能用了，设置为单数容错率更高。</span><br><span class="line">Zookeeper</span><br><span class="line"></span><br><span class="line">157. zookeeper 是什么？</span><br><span class="line"></span><br><span class="line">zookeeper 是一个分布式的，开放源码的分布式应用程序协调服务，是 google chubby 的开源实现，是 hadoop 和 hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件，提供的功能包括：配置维护、域名服务、分布式同步、组服务等。</span><br><span class="line"></span><br><span class="line">158. zookeeper 都有哪些功能？</span><br><span class="line"></span><br><span class="line">集群管理：监控节点存活状态、运行请求等。</span><br><span class="line">主节点选举：主节点挂掉了之后可以从备用的节点开始新一轮选主，主节点选举说的就是这个选举的过程，使用 zookeeper 可以协助完成这个过程。</span><br><span class="line">分布式锁：zookeeper 提供两种锁：独占锁、共享锁。独占锁即一次只能有一个线程使用资源，共享锁是读锁共享，读写互斥，即可以有多线线程同时读同一个资源，如果要使用写锁也只能有一个线程使用。zookeeper可以对分布式锁进行控制。</span><br><span class="line">命名服务：在分布式系统中，通过使用命名服务，客户端应用能够根据指定名字来获取资源或服务的地址，提供者等信息。</span><br><span class="line">159. zookeeper 有几种部署模式？</span><br><span class="line"></span><br><span class="line">zookeeper 有三种部署模式：</span><br><span class="line"></span><br><span class="line">单机部署：一台集群上运行；</span><br><span class="line">集群部署：多台集群运行；</span><br><span class="line">伪集群部署：一台集群启动多个 zookeeper 实例运行。</span><br><span class="line">160. zookeeper 怎么保证主从节点的状态同步？</span><br><span class="line"></span><br><span class="line">zookeeper 的核心是原子广播，这个机制保证了各个 server 之间的同步。实现这个机制的协议叫做 zab 协议。 zab 协议有两种模式，分别是恢复模式（选主）和广播模式（同步）。当服务启动或者在领导者崩溃后，zab 就进入了恢复模式，当领导者被选举出来，且大多数 server 完成了和 leader 的状态同步以后，恢复模式就结束了。状态同步保证了 leader 和 server 具有相同的系统状态。</span><br><span class="line"></span><br><span class="line">161. 集群中为什么要有主节点？</span><br><span class="line"></span><br><span class="line">在分布式环境中，有些业务逻辑只需要集群中的某一台机器进行执行，其他的机器可以共享这个结果，这样可以大大减少重复计算，提高性能，所以就需要主节点。</span><br><span class="line"></span><br><span class="line">162. 集群中有 3 台服务器，其中一个节点宕机，这个时候 zookeeper 还可以使用吗？</span><br><span class="line"></span><br><span class="line">可以继续使用，单数服务器只要没超过一半的服务器宕机就可以继续使用。</span><br><span class="line"></span><br><span class="line">163. 说一下 zookeeper 的通知机制？</span><br><span class="line"></span><br><span class="line">客户端端会对某个 znode 建立一个 watcher 事件，当该 znode 发生变化时，这些客户端会收到 zookeeper 的通知，然后客户端可以根据 znode 变化来做出业务上的改变。</span><br><span class="line"></span><br><span class="line">MySQL</span><br><span class="line"></span><br><span class="line">164. 数据库的三范式是什么？</span><br><span class="line"></span><br><span class="line">第一范式：强调的是列的原子性，即数据库表的每一列都是不可分割的原子数据项。</span><br><span class="line">第二范式：要求实体的属性完全依赖于主关键字。所谓完全依赖是指不能存在仅依赖主关键字一部分的属性。</span><br><span class="line">第三范式：任何非主属性不依赖于其它非主属性。</span><br><span class="line">165. 一张自增表里面总共有 7 条数据，删除了最后 2 条数据，重启 MySQL 数据库，又插入了一条数据，此时 id 是几？</span><br><span class="line"></span><br><span class="line">表类型如果是 MyISAM ，那 id 就是 8。</span><br><span class="line">表类型如果是 InnoDB，那 id 就是 6。</span><br><span class="line">InnoDB 表只会把自增主键的最大 id 记录在内存中，所以重启之后会导致最大 id 丢失。</span><br><span class="line"></span><br><span class="line">166. 如何获取当前数据库版本？</span><br><span class="line"></span><br><span class="line">使用 select version() 获取当前 MySQL 数据库版本。</span><br><span class="line"></span><br><span class="line">167. 说一下 ACID 是什么？</span><br><span class="line"></span><br><span class="line">Atomicity（原子性）：一个事务（transaction）中的所有操作，或者全部完成，或者全部不完成，不会结束在中间某个环节。事务在执行过程中发生错误，会被恢复（Rollback）到事务开始前的状态，就像这个事务从来没有执行过一样。即，事务不可分割、不可约简。</span><br><span class="line">Consistency（一致性）：在事务开始之前和事务结束以后，数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设约束、触发器、级联回滚等。</span><br><span class="line">Isolation（隔离性）：数据库允许多个并发事务同时对其数据进行读写和修改的能力，隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别，包括读未提交（Read uncommitted）、读提交（read committed）、可重复读（repeatable read）和串行化（Serializable）。</span><br><span class="line">Durability（持久性）：事务处理结束后，对数据的修改就是永久的，即便系统故障也不会丢失。</span><br><span class="line">168. char 和 varchar 的区别是什么？</span><br><span class="line"></span><br><span class="line">char(n) ：固定长度类型，比如订阅 char(10)，当你输入&quot;abc&quot;三个字符的时候，它们占的空间还是 10 个字节，其他 7 个是空字节。</span><br><span class="line">chat 优点：效率高；缺点：占用空间；适用场景：存储密码的 md5 值，固定长度的，使用 char 非常合适。</span><br><span class="line"></span><br><span class="line">varchar(n) ：可变长度，存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度。</span><br><span class="line">所以，从空间上考虑 varcahr 比较合适；从效率上考虑 char 比较合适，二者使用需要权衡。</span><br><span class="line"></span><br><span class="line">169. float 和 double 的区别是什么？</span><br><span class="line"></span><br><span class="line">float 最多可以存储 8 位的十进制数，并在内存中占 4 字节。</span><br><span class="line">double 最可可以存储 16 位的十进制数，并在内存中占 8 字节。</span><br><span class="line">170. MySQL 的内连接、左连接、右连接有什么区别？</span><br><span class="line"></span><br><span class="line">内连接关键字：inner join；左连接：left join；右连接：right join。</span><br><span class="line"></span><br><span class="line">内连接是把匹配的关联数据显示出来；左连接是左边的表全部显示出来，右边的表显示出符合条件的数据；右连接正好相反。</span><br><span class="line"></span><br><span class="line">171. MySQL 索引是怎么实现的？</span><br><span class="line"></span><br><span class="line">索引是满足某种特定查找算法的数据结构，而这些数据结构会以某种方式指向数据，从而实现高效查找数据。</span><br><span class="line"></span><br><span class="line">具体来说 MySQL 中的索引，不同的数据引擎实现有所不同，但目前主流的数据库引擎的索引都是 B+ 树实现的，B+ 树的搜索效率，可以到达二分法的性能，找到数据区域之后就找到了完整的数据结构了，所有索引的性能也是更好的。</span><br><span class="line"></span><br><span class="line">172. 怎么验证 MySQL 的索引是否满足需求？</span><br><span class="line"></span><br><span class="line">使用 explain 查看 SQL 是如何执行查询语句的，从而分析你的索引是否满足需求。</span><br><span class="line"></span><br><span class="line">explain 语法：explain select * from table where type=1。</span><br><span class="line"></span><br><span class="line">173. 说一下数据库的事务隔离？</span><br><span class="line"></span><br><span class="line">MySQL 的事务隔离是在 MySQL. ini 配置文件里添加的，在文件的最后添加：</span><br><span class="line"></span><br><span class="line">transaction-isolation = REPEATABLE-READ</span><br><span class="line">可用的配置值：READ-UNCOMMITTED、READ-COMMITTED、REPEATABLE-READ、SERIALIZABLE。</span><br><span class="line"></span><br><span class="line">READ-UNCOMMITTED：未提交读，最低隔离级别、事务未提交前，就可被其他事务读取（会出现幻读、脏读、不可重复读）。</span><br><span class="line">READ-COMMITTED：提交读，一个事务提交后才能被其他事务读取到（会造成幻读、不可重复读）。</span><br><span class="line">REPEATABLE-READ：可重复读，默认级别，保证多次读取同一个数据时，其值都和事务开始时候的内容是一致，禁止读取到别的事务未提交的数据（会造成幻读）。</span><br><span class="line">SERIALIZABLE：序列化，代价最高最可靠的隔离级别，该隔离级别能防止脏读、不可重复读、幻读。</span><br><span class="line">脏读 ：表示一个事务能够读取另一个事务中还未提交的数据。比如，某个事务尝试插入记录 A，此时该事务还未提交，然后另一个事务尝试读取到了记录 A。</span><br><span class="line"></span><br><span class="line">不可重复读 ：是指在一个事务内，多次读同一数据。</span><br><span class="line"></span><br><span class="line">幻读 ：指同一个事务内多次查询返回的结果集不一样。比如同一个事务 A 第一次查询时候有 n 条记录，但是第二次同等条件下查询却有 n+1 条记录，这就好像产生了幻觉。发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据，同一个记录的数据内容被修改了，所有数据行的记录就变多或者变少了。</span><br><span class="line"></span><br><span class="line">174. 说一下 MySQL 常用的引擎？</span><br><span class="line"></span><br><span class="line">InnoDB 引擎：mysql 5.1 后默认的数据库引擎，提供了对数据库 acid 事务的支持，并且还提供了行级锁和外键的约束，它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候，InnoDB 会在内存中建立缓冲池，用于缓冲数据和索引。但是该引擎是不支持全文搜索，同时启动也比较的慢，它是不会保存表的行数的，所以当进行 select count(*) from table 指令的时候，需要进行扫描全表。由于锁的粒度小，写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。</span><br><span class="line"></span><br><span class="line">MyIASM 引擎：不提供事务的支持，也不支持行级锁和外键。因此当执行插入和更新语句时，即执行写操作的时候需要锁定这个表，所以会导致效率会降低。不过和 InnoDB 不同的是，MyIASM 引擎是保存了表的行数，于是当进行 select count(*) from table 语句时，可以直接的读取已经保存的值而不需要进行扫描全表。所以，如果表的读操作远远多于写操作时，并且不需要事务的支持的，可以将 MyIASM 作为数据库引擎的首选。</span><br><span class="line"></span><br><span class="line">175. 说一下 MySQL 的行锁和表锁？</span><br><span class="line"></span><br><span class="line">MyISAM 只支持表锁，InnoDB 支持表锁和行锁，默认为行锁。</span><br><span class="line"></span><br><span class="line">表级锁：开销小，加锁快，不会出现死锁。锁定粒度大，发生锁冲突的概率最高，并发量最低。</span><br><span class="line">行级锁：开销大，加锁慢，会出现死锁。锁力度小，发生锁冲突的概率小，并发度最高。</span><br><span class="line">176. 说一下乐观锁和悲观锁？</span><br><span class="line"></span><br><span class="line">乐观锁：每次去拿数据的时候都认为别人不会修改，所以不会上锁，但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。</span><br><span class="line">悲观锁：每次去拿数据的时候都认为别人会修改，所以每次在拿数据的时候都会上锁，这样别人想拿这个数据就会阻止，直到这个锁被释放。</span><br><span class="line">数据库的乐观锁需要自己实现，在表里面添加一个 version 字段，每次修改成功值加 1，这样每次修改的时候先对比一下，自己拥有的 version 和数据库现在的 version 是否一致，如果不一致就不修改，这样就实现了乐观锁。</span><br><span class="line"></span><br><span class="line">177. MySQL 问题排查都有哪些手段？</span><br><span class="line"></span><br><span class="line">使用 show processlist 命令查看当前所有连接信息。</span><br><span class="line">使用 explain 命令查询 SQL 语句执行计划。</span><br><span class="line">开启慢查询日志，查看慢查询的 SQL。</span><br><span class="line">178. 如何做 MySQL 的性能优化？</span><br><span class="line"></span><br><span class="line">为搜索字段创建索引。</span><br><span class="line">避免使用 select *，列出需要查询的字段。</span><br><span class="line">垂直分割分表。</span><br><span class="line">选择正确的存储引擎。</span><br><span class="line">Redis</span><br><span class="line"></span><br><span class="line">179. Redis 是什么？都有哪些使用场景？</span><br><span class="line"></span><br><span class="line">Redis 是一个使用 C 语言开发的高速缓存数据库。</span><br><span class="line"></span><br><span class="line">Redis 使用场景：</span><br><span class="line"></span><br><span class="line">记录帖子点赞数、点击数、评论数；</span><br><span class="line">缓存近期热帖；</span><br><span class="line">缓存文章详情信息；</span><br><span class="line">记录用户会话信息。</span><br><span class="line">180. Redis 有哪些功能？</span><br><span class="line"></span><br><span class="line">数据缓存功能</span><br><span class="line">分布式锁的功能</span><br><span class="line">支持数据持久化</span><br><span class="line">支持事务</span><br><span class="line">支持消息队列</span><br><span class="line">181. Redis 和 memcache 有什么区别？</span><br><span class="line"></span><br><span class="line">存储方式不同：memcache 把数据全部存在内存之中，断电后会挂掉，数据不能超过内存大小；Redis 有部份存在硬盘上，这样能保证数据的持久性。</span><br><span class="line">数据支持类型：memcache 对数据类型支持相对简单；Redis 有复杂的数据类型。</span><br><span class="line">使用底层模型不同：它们之间底层实现方式，以及与客户端之间通信的应用协议不一样，Redis 自己构建了 vm 机制，因为一般的系统调用系统函数的话，会浪费一定的时间去移动和请求。</span><br><span class="line">value 值大小不同：Redis 最大可以达到 512mb；memcache 只有 1mb。</span><br><span class="line">182. Redis 为什么是单线程的？</span><br><span class="line"></span><br><span class="line">因为 cpu 不是 Redis 的瓶颈，Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现，而且 cpu 又不会成为瓶颈，那就顺理成章地采用单线程的方案了。</span><br><span class="line"></span><br><span class="line">关于 Redis 的性能，官方网站也有，普通笔记本轻松处理每秒几十万的请求。</span><br><span class="line"></span><br><span class="line">而且单线程并不代表就慢 nginx 和 nodejs 也都是高性能单线程的代表。</span><br><span class="line"></span><br><span class="line">183. 什么是缓存穿透？怎么解决？</span><br><span class="line"></span><br><span class="line">缓存穿透：指查询一个一定不存在的数据，由于缓存是不命中时需要从数据库查询，查不到数据则不写入缓存，这将导致这个不存在的数据每次请求都要到数据库去查询，造成缓存穿透。</span><br><span class="line"></span><br><span class="line">解决方案：最简单粗暴的方法如果一个查询返回的数据为空（不管是数据不存在，还是系统故障），我们就把这个空结果进行缓存，但它的过期时间会很短，最长不超过五分钟。</span><br><span class="line"></span><br><span class="line">184. Redis 支持的数据类型有哪些？</span><br><span class="line"></span><br><span class="line">Redis 支持的数据类型：string（字符串）、list（列表）、hash（字典）、set（集合）、zset（有序集合）。</span><br><span class="line"></span><br><span class="line">185. Redis 支持的 Java 客户端都有哪些？</span><br><span class="line"></span><br><span class="line">支持的 Java 客户端有 Redisson、jedis、lettuce 等。</span><br><span class="line"></span><br><span class="line">186. jedis 和 Redisson 有哪些区别？</span><br><span class="line"></span><br><span class="line">jedis：提供了比较全面的 Redis 命令的支持。</span><br><span class="line">Redisson：实现了分布式和可扩展的 Java 数据结构，与 jedis 相比 Redisson 的功能相对简单，不支持排序、事务、管道、分区等 Redis 特性。</span><br><span class="line">187. 怎么保证缓存和数据库数据的一致性？</span><br><span class="line"></span><br><span class="line">合理设置缓存的过期时间。</span><br><span class="line">新增、更改、删除数据库操作时同步更新 Redis，可以使用事物机制来保证数据的一致性。</span><br><span class="line">188. Redis 持久化有几种方式？</span><br><span class="line"></span><br><span class="line">Redis 的持久化有两种方式，或者说有两种策略：</span><br><span class="line"></span><br><span class="line">RDB（Redis Database）：指定的时间间隔能对你的数据进行快照存储。</span><br><span class="line">AOF（Append Only File）：每一个收到的写命令都通过write函数追加到文件中。</span><br><span class="line">189. Redis 怎么实现分布式锁？</span><br><span class="line"></span><br><span class="line">Redis 分布式锁其实就是在系统里面占一个“坑”，其他程序也要占“坑”的时候，占用成功了就可以继续执行，失败了就只能放弃或稍后重试。</span><br><span class="line"></span><br><span class="line">占坑一般使用 setnx(set if not exists)指令，只允许被一个程序占有，使用完调用 del 释放锁。</span><br><span class="line"></span><br><span class="line">190. Redis 分布式锁有什么缺陷？</span><br><span class="line"></span><br><span class="line">Redis 分布式锁不能解决超时的问题，分布式锁有一个超时时间，程序的执行如果超出了锁的超时时间就会出现问题。</span><br><span class="line"></span><br><span class="line">191. Redis 如何做内存优化？</span><br><span class="line"></span><br><span class="line">尽量使用 Redis 的散列表，把相关的信息放到散列表里面存储，而不是把每个字段单独存储，这样可以有效的减少内存使用。比如将 Web 系统的用户对象，应该放到散列表里面再整体存储到 Redis，而不是把用户的姓名、年龄、密码、邮箱等字段分别设置 key 进行存储。</span><br><span class="line"></span><br><span class="line">192. Redis 淘汰策略有哪些？</span><br><span class="line"></span><br><span class="line">volatile-lru：从已设置过期时间的数据集（server. db[i]. expires）中挑选最近最少使用的数据淘汰。</span><br><span class="line"></span><br><span class="line">volatile-ttl：从已设置过期时间的数据集（server. db[i]. expires）中挑选将要过期的数据淘汰。</span><br><span class="line"></span><br><span class="line">volatile-random：从已设置过期时间的数据集（server. db[i]. expires）中任意选择数据淘汰。</span><br><span class="line"></span><br><span class="line">allkeys-lru：从数据集（server. db[i]. dict）中挑选最近最少使用的数据淘汰。</span><br><span class="line"></span><br><span class="line">allkeys-random：从数据集（server. db[i]. dict）中任意选择数据淘汰。</span><br><span class="line"></span><br><span class="line">no-enviction（驱逐）：禁止驱逐数据。</span><br><span class="line"></span><br><span class="line">193. Redis 常见的性能问题有哪些？该如何解决？</span><br><span class="line"></span><br><span class="line">主服务器写内存快照，会阻塞主线程的工作，当快照比较大时对性能影响是非常大的，会间断性暂停服务，所以主服务器最好不要写内存快照。</span><br><span class="line">Redis 主从复制的性能问题，为了主从复制的速度和连接的稳定性，主从库最好在同一个局域网内。</span><br><span class="line">JVM</span><br><span class="line"></span><br><span class="line">194. 说一下 JVM 的主要组成部分？及其作用？</span><br><span class="line"></span><br><span class="line">类加载器（ClassLoader）</span><br><span class="line">运行时数据区（Runtime Data Area）</span><br><span class="line">执行引擎（Execution Engine）</span><br><span class="line">本地库接口（Native Interface）</span><br><span class="line">组件的作用： 首先通过类加载器（ClassLoader）会把 Java 代码转换成字节码，运行时数据区（Runtime Data Area）再把字节码加载到内存中，而字节码文件只是 JVM 的一套指令集规范，并不能直接交给底层操作系统去执行，因此需要特定的命令解析器执行引擎（Execution Engine），将字节码翻译成底层系统指令，再交由 CPU 去执行，而这个过程中需要调用其他语言的本地库接口（Native Interface）来实现整个程序的功能。</span><br><span class="line"></span><br><span class="line">195. 说一下 JVM 运行时数据区？</span><br><span class="line"></span><br><span class="line">不同虚拟机的运行时数据区可能略微有所不同，但都会遵从 Java 虚拟机规范， Java 虚拟机规范规定的区域分为以下 5 个部分：</span><br><span class="line"></span><br><span class="line">程序计数器（Program Counter Register）：当前线程所执行的字节码的行号指示器，字节码解析器的工作是通过改变这个计数器的值，来选取下一条需要执行的字节码指令，分支、循环、跳转、异常处理、线程恢复等基础功能，都需要依赖这个计数器来完成；</span><br><span class="line"></span><br><span class="line">Java 虚拟机栈（Java Virtual Machine Stacks）：用于存储局部变量表、操作数栈、动态链接、方法出口等信息；</span><br><span class="line"></span><br><span class="line">本地方法栈（Native Method Stack）：与虚拟机栈的作用是一样的，只不过虚拟机栈是服务 Java 方法的，而本地方法栈是为虚拟机调用 Native 方法服务的；</span><br><span class="line"></span><br><span class="line">Java 堆（Java Heap）：Java 虚拟机中内存最大的一块，是被所有线程共享的，几乎所有的对象实例都在这里分配内存；</span><br><span class="line"></span><br><span class="line">方法区（Methed Area）：用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。</span><br><span class="line"></span><br><span class="line">196. 说一下堆栈的区别？</span><br><span class="line"></span><br><span class="line">功能方面：堆是用来存放对象的，栈是用来执行程序的。</span><br><span class="line">共享性：堆是线程共享的，栈是线程私有的。</span><br><span class="line">空间大小：堆大小远远大于栈。</span><br><span class="line">197. 队列和栈是什么？有什么区别？</span><br><span class="line"></span><br><span class="line">队列和栈都是被用来预存储数据的。</span><br><span class="line"></span><br><span class="line">队列允许先进先出检索元素，但也有例外的情况，Deque 接口允许从两端检索元素。</span><br><span class="line"></span><br><span class="line">栈和队列很相似，但它运行对元素进行后进先出进行检索。</span><br><span class="line"></span><br><span class="line">198. 什么是双亲委派模型？</span><br><span class="line"></span><br><span class="line">在介绍双亲委派模型之前先说下类加载器。对于任意一个类，都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性，每一个类加载器，都有一个独立的类名称空间。类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存，然后再转化为 class 对象。</span><br><span class="line"></span><br><span class="line">类加载器分类：</span><br><span class="line"></span><br><span class="line">启动类加载器（Bootstrap ClassLoader），是虚拟机自身的一部分，用来加载Java_HOME/lib/目录中的，或者被 -Xbootclasspath 参数所指定的路径中并且被虚拟机识别的类库；</span><br><span class="line">其他类加载器：</span><br><span class="line">扩展类加载器（Extension ClassLoader）：负责加载\lib\ext目录或Java. ext. dirs系统变量指定的路径中的所有类库；</span><br><span class="line">应用程序类加载器（Application ClassLoader）。负责加载用户类路径（classpath）上的指定类库，我们可以直接使用这个类加载器。一般情况，如果我们没有自定义类加载器默认就是用这个加载器。</span><br><span class="line">双亲委派模型：如果一个类加载器收到了类加载的请求，它首先不会自己去加载这个类，而是把这个请求委派给父类加载器去完成，每一层的类加载器都是如此，这样所有的加载请求都会被传送到顶层的启动类加载器中，只有当父加载无法完成加载请求（它的搜索范围中没找到所需的类）时，子加载器才会尝试去加载类。</span><br><span class="line"></span><br><span class="line">199. 说一下类装载的执行过程？</span><br><span class="line"></span><br><span class="line">类装载分为以下 5 个步骤：</span><br><span class="line"></span><br><span class="line">加载：根据查找路径找到相应的 class 文件然后导入；</span><br><span class="line">检查：检查加载的 class 文件的正确性；</span><br><span class="line">准备：给类中的静态变量分配内存空间；</span><br><span class="line">解析：虚拟机将常量池中的符号引用替换成直接引用的过程。符号引用就理解为一个标示，而在直接引用直接指向内存中的地址；</span><br><span class="line">初始化：对静态变量和静态代码块执行初始化工作。</span><br><span class="line">200. 怎么判断对象是否可以被回收？</span><br><span class="line"></span><br><span class="line">一般有两种方法来判断：</span><br><span class="line"></span><br><span class="line">引用计数器：为每个对象创建一个引用计数，有对象引用时计数器 +1，引用被释放时计数 -1，当计数器为 0 时就可以被回收。它有一个缺点不能解决循环引用的问题；</span><br><span class="line">可达性分析：从 GC Roots 开始向下搜索，搜索所走过的路径称为引用链。当一个对象到 GC Roots 没有任何引用链相连时，则证明此对象是可以被回收的。</span><br><span class="line">201. Java 中都有哪些引用类型？</span><br><span class="line"></span><br><span class="line">强引用：发生 gc 的时候不会被回收。</span><br><span class="line">软引用：有用但不是必须的对象，在发生内存溢出之前会被回收。</span><br><span class="line">弱引用：有用但不是必须的对象，在下一次GC时会被回收。</span><br><span class="line">虚引用（幽灵引用/幻影引用）：无法通过虚引用获得对象，用 PhantomReference 实现虚引用，虚引用的用途是在 gc 时返回一个通知。</span><br><span class="line">202. 说一下 JVM 有哪些垃圾回收算法？</span><br><span class="line"></span><br><span class="line">标记-清除算法：标记无用对象，然后进行清除回收。缺点：效率不高，无法清除垃圾碎片。</span><br><span class="line">标记-整理算法：标记无用对象，让所有存活的对象都向一端移动，然后直接清除掉端边界以外的内存。</span><br><span class="line">复制算法：按照容量划分二个大小相等的内存区域，当一块用完的时候将活着的对象复制到另一块上，然后再把已使用的内存空间一次清理掉。缺点：内存使用率不高，只有原来的一半。</span><br><span class="line">分代算法：根据对象存活周期的不同将内存划分为几块，一般是新生代和老年代，新生代基本采用复制算法，老年代采用标记整理算法。</span><br><span class="line">203. 说一下 JVM 有哪些垃圾回收器？</span><br><span class="line"></span><br><span class="line">Serial：最早的单线程串行垃圾回收器。</span><br><span class="line">Serial Old：Serial 垃圾回收器的老年版本，同样也是单线程的，可以作为 CMS 垃圾回收器的备选预案。</span><br><span class="line">ParNew：是 Serial 的多线程版本。</span><br><span class="line">Parallel 和 ParNew 收集器类似是多线程的，但 Parallel 是吞吐量优先的收集器，可以牺牲等待时间换取系统的吞吐量。</span><br><span class="line">Parallel Old 是 Parallel 老生代版本，Parallel 使用的是复制的内存回收算法，Parallel Old 使用的是标记-整理的内存回收算法。</span><br><span class="line">CMS：一种以获得最短停顿时间为目标的收集器，非常适用 B/S 系统。</span><br><span class="line">G1：一种兼顾吞吐量和停顿时间的 GC 实现，是 JDK 9 以后的默认 GC 选项。</span><br><span class="line">204. 详细介绍一下 CMS 垃圾回收器？</span><br><span class="line"></span><br><span class="line">CMS 是英文 Concurrent Mark-Sweep 的简称，是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。对于要求服务器响应速度的应用上，这种垃圾回收器非常适合。在启动 JVM 的参数加上“-XX:+UseConcMarkSweepGC”来指定使用 CMS 垃圾回收器。</span><br><span class="line"></span><br><span class="line">CMS 使用的是标记-清除的算法实现的，所以在 gc 的时候回产生大量的内存碎片，当剩余内存不能满足程序运行要求时，系统将会出现 Concurrent Mode Failure，临时 CMS 会采用 Serial Old 回收器进行垃圾清除，此时的性能将会被降低。</span><br><span class="line"></span><br><span class="line">205. 新生代垃圾回收器和老生代垃圾回收器都有哪些？有什么区别？</span><br><span class="line"></span><br><span class="line">新生代回收器：Serial、ParNew、Parallel Scavenge</span><br><span class="line">老年代回收器：Serial Old、Parallel Old、CMS</span><br><span class="line">整堆回收器：G1</span><br><span class="line">新生代垃圾回收器一般采用的是复制算法，复制算法的优点是效率高，缺点是内存利用率低；老年代回收器一般采用的是标记-整理的算法进行垃圾回收。</span><br><span class="line"></span><br><span class="line">206. 简述分代垃圾回收器是怎么工作的？</span><br><span class="line"></span><br><span class="line">分代回收器有两个分区：老生代和新生代，新生代默认的空间占比总空间的 1/3，老生代的默认占比是 2/3。</span><br><span class="line"></span><br><span class="line">新生代使用的是复制算法，新生代里有 3 个分区：Eden、To Survivor、From Survivor，它们的默认占比是 8:1:1，它的执行流程如下：</span><br><span class="line"></span><br><span class="line">把 Eden + From Survivor 存活的对象放入 To Survivor 区；</span><br><span class="line">清空 Eden 和 From Survivor 分区；</span><br><span class="line">From Survivor 和 To Survivor 分区交换，From Survivor 变 To Survivor，To Survivor 变 From Survivor。</span><br><span class="line">每次在 From Survivor 到 To Survivor 移动时都存活的对象，年龄就 +1，当年龄到达 15（默认配置是 15）时，升级为老生代。大对象也会直接进入老生代。</span><br><span class="line"></span><br><span class="line">老生代当空间占用到达某个值之后就会触发全局垃圾收回，一般使用标记整理的执行算法。以上这些循环往复就构成了整个分代垃圾回收的整体执行流程。</span><br><span class="line"></span><br><span class="line">207. 说一下 JVM 调优的工具？</span><br><span class="line"></span><br><span class="line">JDK 自带了很多监控工具，都位于 JDK 的 bin 目录下，其中最常用的是 jconsole 和 jvisualvm 这两款视图监控工具。</span><br><span class="line"></span><br><span class="line">jconsole：用于对 JVM 中的内存、线程和类等进行监控；</span><br><span class="line">jvisualvm：JDK 自带的全能分析工具，可以分析：内存快照、线程快照、程序死锁、监控内存的变化、gc 变化等。</span><br><span class="line">208. 常用的 JVM 调优的参数都有哪些？</span><br><span class="line"></span><br><span class="line">-Xms2g：初始化推大小为 2g；</span><br><span class="line">-Xmx2g：堆最大内存为 2g；</span><br><span class="line">-XX:NewRatio=4：设置年轻的和老年代的内存比例为 1:4；</span><br><span class="line">-XX:SurvivorRatio=8：设置新生代 Eden 和 Survivor 比例为 8:2；</span><br><span class="line">–XX:+UseParNewGC：指定使用 ParNew + Serial Old 垃圾回收器组合；</span><br><span class="line">-XX:+UseParallelOldGC：指定使用 ParNew + ParNew Old 垃圾回收器组合；</span><br><span class="line">-XX:+UseConcMarkSweepGC：指定使用 CMS + Serial Old 垃圾回收器组合；</span><br><span class="line">-XX:+PrintGC：开启打印 gc 信息；</span><br><span class="line">-XX:+PrintGCDetails：打印 gc 详细信息。</span><br></pre></td></tr></table></figure>
      
    </div>
    <footer class="article-footer">
      <a data-url="http://yoursite.com/2019/04/06/GItChat_java/" data-id="ck8d0lrvq008zusuwhg913a8r" class="article-share-link">Share</a>
      
      
  <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/java/">java</a></li></ul>

    </footer>
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2019/04/08/sql_基础使用/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          基础sql使用
        
      </div>
    </a>
  
  
    <a href="/2019/03/03/rabbitMq/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">rabbitMq</div>
    </a>
  
</nav>

  
</article>

</section>
        
          <aside id="sidebar">
  
    

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tags</h3>
    <div class="widget">
      <ul class="tag-list"><li class="tag-list-item"><a class="tag-list-link" href="/tags/Design-Patterns/">Design Patterns</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Git/">Git</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Html/">Html</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Http/">Http</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript/">JavaScript</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Sort/">Sort</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/algorithm/">algorithm</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/docker/">docker</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/elasticsearch/">elasticsearch</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/hexo/">hexo</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/idea/">idea</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/java/">java</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/jvm/">jvm</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/linux/">linux</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/logstash/">logstash</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/mysql/">mysql</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/php/">php</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/pytest/">pytest</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/python/">python</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/springboot/">springboot</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/util/">util</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/vue/">vue</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/wechat/">wechat</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/我的世界/">我的世界</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/支付转账/">支付转账</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/消息队列/">消息队列</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/简单算法题/">简单算法题</a></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/线程/">线程</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget tagcloud">
      <a href="/tags/Design-Patterns/" style="font-size: 16.36px;">Design Patterns</a> <a href="/tags/Git/" style="font-size: 10px;">Git</a> <a href="/tags/Html/" style="font-size: 10px;">Html</a> <a href="/tags/Http/" style="font-size: 12.73px;">Http</a> <a href="/tags/JavaScript/" style="font-size: 15.45px;">JavaScript</a> <a href="/tags/Sort/" style="font-size: 18.18px;">Sort</a> <a href="/tags/algorithm/" style="font-size: 10.91px;">algorithm</a> <a href="/tags/docker/" style="font-size: 17.27px;">docker</a> <a href="/tags/elasticsearch/" style="font-size: 10px;">elasticsearch</a> <a href="/tags/hexo/" style="font-size: 10px;">hexo</a> <a href="/tags/idea/" style="font-size: 10px;">idea</a> <a href="/tags/java/" style="font-size: 20px;">java</a> <a href="/tags/jvm/" style="font-size: 11.82px;">jvm</a> <a href="/tags/linux/" style="font-size: 13.64px;">linux</a> <a href="/tags/logstash/" style="font-size: 12.73px;">logstash</a> <a href="/tags/mysql/" style="font-size: 14.55px;">mysql</a> <a href="/tags/php/" style="font-size: 11.82px;">php</a> <a href="/tags/pytest/" style="font-size: 10px;">pytest</a> <a href="/tags/python/" style="font-size: 13.64px;">python</a> <a href="/tags/springboot/" style="font-size: 17.27px;">springboot</a> <a href="/tags/util/" style="font-size: 19.09px;">util</a> <a href="/tags/vue/" style="font-size: 10px;">vue</a> <a href="/tags/wechat/" style="font-size: 10.91px;">wechat</a> <a href="/tags/我的世界/" style="font-size: 10px;">我的世界</a> <a href="/tags/支付转账/" style="font-size: 13.64px;">支付转账</a> <a href="/tags/消息队列/" style="font-size: 10.91px;">消息队列</a> <a href="/tags/简单算法题/" style="font-size: 10px;">简单算法题</a> <a href="/tags/线程/" style="font-size: 11.82px;">线程</a>
    </div>
  </div>

  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Archives</h3>
    <div class="widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/03/">March 2020</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/10/">October 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/08/">August 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/06/">June 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/04/">April 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/03/">March 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/02/">February 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/01/">January 2019</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/12/">December 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/11/">November 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/10/">October 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/09/">September 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/07/">July 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/06/">June 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/05/">May 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/04/">April 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/03/">March 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/02/">February 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2018/01/">January 2018</a></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2017/12/">December 2017</a></li></ul>
    </div>
  </div>


  
    
  <div class="widget-wrap">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget">
      <ul>
        
          <li>
            <a href="/2020/03/29/UML/">UML</a>
          </li>
        
          <li>
            <a href="/2020/03/29/hello-world/">Hello World</a>
          </li>
        
          <li>
            <a href="/2019/10/27/python_字典/">python_dict</a>
          </li>
        
          <li>
            <a href="/2019/10/27/python_时间/">python-时间</a>
          </li>
        
          <li>
            <a href="/2019/10/26/git取消修改/">git-取消修改</a>
          </li>
        
      </ul>
    </div>
  </div>

  
</aside>
        
      </div>
      <footer id="footer">
  
  <div class="outer">
    <div id="footer-info" class="inner">
      &copy; 2020 chen v<br>
      Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
    </div>
  </div>
</footer>
    </div>
    <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
</nav>
    

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>


  <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  <script src="/fancybox/jquery.fancybox.pack.js"></script>


<script src="/js/script.js"></script>



  </div>
</body>
</html>